描述
64bit環境中運行32位android系統,經常遇到運行一段時間之後,打開大部分軟件會出現卡死,屏幕黑掉的問題
分析解決
- 運行一段時間會出現黑屏,所以懷疑爲資源不足,排查方向爲CPU/內存/進程數等限制,經過檢查未發現問題;
- 懷疑是某個沒被關注的點不滿足要求,增加日誌,通過調測發現經常出現futex的錯誤,但是沒有引起足夠關注,依舊關注在內存使用上;
- 發現設置應用中顯示的內存使用數據不對,發現meminfo中數據不對,後修復後,問題沒有解決。
- 懷疑內存長時間拷貝導致出現問題,測試程序模擬不斷進行內存拷貝,發現大內存拷貝會奔潰,後發現存在單個進程最大使用內存限制,不是黑屏原因。
- 懷疑是binder不夠用,測試程序模擬不斷申請binder調用,排查binder釋放是否正常,結果顯示正常。
- 後發現正常情況下pid會在超過65535後恢復到1重新使用,而生產環境最大限制已經調高。經過測試發現,PID使用超過該閾值後就很容易觸發問題,而在未超過時不會出現問題。
- 是trace跟蹤pid觸發問題時的堆棧調用情況發現,報錯信息依舊爲futex部分卡主,結合之前也有發現這個問題,調整排查方向。
- 經過分析對比,問題確定爲mutex部分可能導致黑屏問題,並且確認該問題爲已存在問題https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md#is-too-small-for-large-pids
- 經過研究分析,32bit android中的bionic的tid字段長度爲16位,且無法擴展,官方在後續提交的PIMutex的patch並不能解決這個問題,根據這個patch,寫了一個tid映射匹配的方案,測試發現解決了大部分問題,在學習強國等少數應用依然無法解決,在排查了常量初始化mutex可能存在的問題後,問題依舊。
- 從確保獲取到的tid不超過65535,研究代碼發現,這部分的實現是利用了kernel的cgroup來實現隔離,利用pidns來實現不同ns的pid分配隔離問題,後嘗試修改pid分配機制,解決問題。