高通android HWC死锁导致拔投屏线冻屏问题解决过程

问题稳定复现手法:主屏有画面刷新时,拔掉DP线,设备冻屏;
现象:ADB可用,但显示冻屏,怀疑死锁导致某CPU卡死;
分析过程:
adb bugreport生成bugreport;使用addr2line将symbol导入后看调用栈,找到有用的一些:

可以看到PresentDisplay的时候,没拿到Lock而__futex_wait_ex:

Stack Trace:RELADDR           FUNCTION                                                                                 000000000004e1b0  syscall+32                                                                               v-------------->  __futex(void volatile*, int, int, timespec const*, int)                                 v-------------->  FutexWithTimeout(void volatile*, int, int, bool, timespec const*, int)                   0000000000052a7c  __futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+148                   v-------------->  NonPI::NormalMutexLock(pthread_mutex_internal_t*, unsigned short, bool, timespec const*) 00000000000b7fb8  NonPI::MutexLockWithTimeout(pthread_mutex_internal_t*, bool, timespec const*)+224   v-------------->  sdm::Locker::Lock()                                                                     v-------------->  sdm::Locker::ScopeLock::ScopeLock(sdm::Locker&) -->sdm/include/utils/locker.h:46         v-------------->  sdm::HWCSession::PresentDisplay(unsigned long, std::__1::shared_ptr*)       

接着看到DestroyPluggableDisplay时也会直接进Wait():

Stack Trace:RELADDR           FUNCTION                               000000000004e1b0  syscall+32                                                                     v-------------->  __futex(void volatile*, int, int, timespec const*, int)                     v-------------->  FutexWithTimeout(void volatile*, int, int, bool, timespec const*, int)           0000000000052a7c  __futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+148            v-------------->  __pthread_cond_timedwait(pthread_cond_internal_t*, pthread_mutex_t*, bool, timespec const*)    00000000000b6054  pthread_cond_wait+84                           v-------------->  sdm::Locker::Wait()                                        v-------------->  sdm::Locker::SequenceWaitScopeLock::SequenceWaitScopeLock(sdm::Locker&)           v-------------->  sdm::HWCSession::DestroyPluggableDisplay(sdm::HWCSession::DisplayMapInfo*)        000000000004ad14  sdm::HWCSession::DestroyDisplay(sdm::HWCSession::DisplayMapInfo*)+232                   

首先看一下PresentDisplay源码:

int32_t HWCSession::PresentDisplay(hwc2_display_t display, shared_ptr *out_retire_fence) {auto status = HWC2::Error::BadDisplay;DTRACE_SCOPED();//首先拿system_locker_ SCOPE_LOCK(system_locker_);   									if (display >= HWCCallbacks::kNumDisplays) {DLOGW("Invalid Display : display = %" PRIu64, display);return HWC2_ERROR_BAD_DISPLAY;}
...if (status != HWC2::Error::None && status != HWC2::Error::NotValidated) {SEQUENCE_CANCEL_SCOPE_LOCK(locker_[target_display]);     						}

通过trace中的行号,能定位到PresentDisplay卡住的地方是ScopeLock

41  class Locker {
42   public:
43    class ScopeLock {
44     public:
45      explicit ScopeLock(Locker& locker) : locker_(locker) {
46        locker_.Lock();
47      }
48  
49      ~ScopeLock() {
50        locker_.Unlock();


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部