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