一、关键字:

点屏失败、render_service挂死

二、问题描述

设备型号:黄鹂

系统版本:OpenHarmony 5.0

代码版本:OpenHarmony-5.0

问题现象:点屏失败,render_service进程挂死。

三、原因分析

3.1 异常现象

适配OpenHarmony 5.0,出现屏幕无法显示的问题,分析日志,发现render_service有crash问题,造成进程挂死。

Module name:render_service
Timestamp:1970-01-01 08:55:25.323
Pid:2430
Uid:1003
Process name:/system/bin/render_service
Process life time:5s
Reason:Signal:SIGSEGV(SEGV_MAPERR)@0x0000000000000408  probably caused by NULL pointer dereference
Fault thread info:
Tid:2430, Name:render_service
#00 pc 0000000000114c18 /system/lib/ld-musl-aarch64.so.1(__pthread_mutex_lock+0)(4ee27b938cbc67571865f41dc666b89b)
#01 pc 00000000000c5998 /system/lib64/libc++.so(std::__h::mutex::lock()+8)(ce78c7142c4dc30f22c706ab8312675080a0eb7a)
#02 pc 0000000000045560 /system/lib64/libhyper_graphic_manager.z.so(OHOS::Rosen::HgmMultiAppStrategy::CleanApp(int)+52)(36414b5add6d65896242aaf61c72cac2)
#03 pc 000000000003b268 /system/lib64/libhyper_graphic_manager.z.so(OHOS::Rosen::HgmFrameRateManager::CleanVote(int)+72)(36414b5add6d65896242aaf61c72cac2)
#04 pc 00000000001fc7a0 /system/lib64/librender_service.z.so(std::__h::__packaged_task_func<OHOS::Rosen::RSRenderServiceConnection::CleanAll(bool)::$_3, std::__h::allocator<OHOS::Rosen::RSRenderServiceConnection::CleanAll(bool)::$_3>, void ()>::operator()() (.c0fbadd1f52afaa2b9a32e7bcbbf384c)+152)(266c05bff09228a579b7d3ac7aec998b)
#05 pc 0000000000179f0c /system/lib64/librender_service.z.so(std::__h::packaged_task<void ()>::operator()()+92)(266c05bff09228a579b7d3ac7aec998b)
#06 pc 0000000000018e34 /system/lib64/chipset-pub-sdk/libeventhandler.z.so(OHOS::AppExecFwk::EventHandler::DistributeEvent(std::__h::unique_ptr<OHOS::AppExecFwk::InnerEvent, void (*)(OHOS::AppExecFwk::InnerEvent*)> const&)+1312)(d003705f2d6110944f64a8821ef4a12e)
#07 pc 0000000000029154 /system/lib64/chipset-pub-sdk/libeventhandler.z.so(OHOS::AppExecFwk::(anonymous namespace)::EventRunnerImpl::ExecuteEventHandler(std::__h::unique_ptr<OHOS::AppExecFwk::InnerEvent, void (*)(OHOS::AppExecFwk::InnerEvent*)>&)+1336)(d003705f2d6110944f64a8821ef4a12e)
#08 pc 0000000000028694 /system/lib64/chipset-pub-sdk/libeventhandler.z.so(OHOS::AppExecFwk::(anonymous namespace)::EventRunnerImpl::Run()+852)(d003705f2d6110944f64a8821ef4a12e)
#09 pc 000000000002ba4c /system/lib64/chipset-pub-sdk/libeventhandler.z.so(OHOS::AppExecFwk::EventRunner::Run()+444)(d003705f2d6110944f64a8821ef4a12e)
#10 pc 0000000000008c90 /system/bin/render_service(main.cfi+232)(34dfe238e775e129dd2a85e6a0294578)
#11 pc 0000000000087d04 /system/lib/ld-musl-aarch64.so.1(libc_start_main_stage2+64)(4ee27b938cbc67571865f41dc666b89b)

3.2 反编译定位代码位置

根据crash信息probably caused by NULL pointer dereference,可能出现空指针。反编译定位代码位置

llvm-addr2line -fCpie librender_service.z.so 1fc7a0
OHOS::Rosen::RSRenderServiceConnection::CleanAll(bool)::$_3::operator()() const at /home/user/0work/5.0-laval-bak/out/oriole/../../foundation/graphic/graphic_2d/rosen/modules/render_service/core/pipeline/rs_render_service_connection.cpp:182
 (inlined by) decltype(std::declval<OHOS::Rosen::RSRenderServiceConnection::CleanAll(bool)::$_3&>()()) std::__h::__invoke[abi:v15004]<OHOS::Rosen::RSRenderServiceConnection::CleanAll(bool)::$_3&>(OHOS::Rosen::RSRenderServiceConnection::CleanAll(bool)::$_3&) at /home/user/0work/5.0-laval-bak/out/oriole/../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/../include/libcxx-ohos/include/c++/v1/__functional/invoke.h:394
 (inlined by) std::__h::__packaged_task_func<OHOS::Rosen::RSRenderServiceConnection::CleanAll(bool)::$_3, std::__h::allocator<OHOS::Rosen::RSRenderServiceConnection::CleanAll(bool)::$_3>, void ()>::operator()() (.c0fbadd1f52afaa2b9a32e7bcbbf384c) at /home/user/0work/5.0-laval-bak/out/oriole/../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/../include/libcxx-ohos/include/c++/v1/future:1694

代码位置如下:

    mainThread_->ScheduleTask(
        [weakThis = wptr<RSRenderServiceConnection>(this)]() {
            sptr<RSRenderServiceConnection> connection = weakThis.promote();
            if (!connection) {
                return;
            }
            RS_TRACE_NAME_FMT("CleanHgmEvent %d", connection->remotePid_);
            // crash位置
            connection->mainThread_->GetFrameRateMgr()->CleanVote(connection->remotePid_);
        }).wait();

初步判断connection->mainThread_->GetFrameRateMgr()指针为空。

对比master分支,相关代码已经修复。

    HgmTaskHandleThread::Instance().ScheduleTask([pid = remotePid_] () {
        RS_TRACE_NAME_FMT("CleanHgmEvent %d", pid);
        HgmConfigCallbackManager::GetInstance()->UnRegisterHgmConfigChangeCallback(pid);
        auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr();
        if (frameRateMgr != nullptr) {
            frameRateMgr->CleanVote(pid);
        }
    }).wait();

四、方案解决

对比master分支,修改相关代码,判断指针是否为空。

diff --git a/rosen/modules/hyper_graphic_manager/core/hgm_screen_manager/hgm_core.cpp b/rosen/modules/hyper_graphic_manager/core/hgm_screen_manager/hgm_core.cpp
index 31f6e4f6f7..b3eff6e2ef 100644
--- a/rosen/modules/hyper_graphic_manager/core/hgm_screen_manager/hgm_core.cpp
+++ b/rosen/modules/hyper_graphic_manager/core/hgm_screen_manager/hgm_core.cpp
@@ -336,7 +336,9 @@ int32_t HgmCore::SetRefreshRateMode(int32_t refreshRateMode)

 void HgmCore::NotifyScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
 {
-    hgmFrameRateMgr_->HandleScreenPowerStatus(id, status);
+    if (hgmFrameRateMgr_ != nullptr) {^M
+        hgmFrameRateMgr_->HandleScreenPowerStatus(id, status);^M
+    }^M

     if (refreshRateModeChangeCallback_ != nullptr) {
         auto refreshRateModeName = GetCurrentRefreshRateModeName();
diff --git a/rosen/modules/render_service/core/pipeline/rs_main_thread.cpp b/rosen/modules/render_service/core/pipeline/rs_main_thread.cpp
index c833a3be7a..f0b16f7bff 100644
--- a/rosen/modules/render_service/core/pipeline/rs_main_thread.cpp
+++ b/rosen/modules/render_service/core/pipeline/rs_main_thread.cpp
@@ -652,17 +652,19 @@ void RSMainThread::Init()
     RSOverdrawController::GetInstance().SetDelegate(delegate);

     frameRateMgr_ = OHOS::Rosen::HgmCore::Instance().GetFrameRateMgr();
-    frameRateMgr_->SetForceUpdateCallback([this](bool idleTimerExpired, bool forceUpdate) {
-        RSMainThread::Instance()->PostTask([this, idleTimerExpired, forceUpdate]() {
-            RS_TRACE_NAME_FMT("RSMainThread::TimerExpiredCallback Run idleTimerExpiredFlag: %s  forceUpdateFlag: %s",
-                idleTimerExpired? "True":"False", forceUpdate? "True": "False");
-            RSMainThread::Instance()->SetForceUpdateUniRenderFlag(forceUpdate);
-            RSMainThread::Instance()->SetIdleTimerExpiredFlag(idleTimerExpired);
-            RS_TRACE_NAME_FMT("DVSyncIsOn: %d", this->rsVSyncDistributor_->IsDVsyncOn());
-            RSMainThread::Instance()->RequestNextVSync("ltpoForceUpdate");
+    if (frameRateMgr_ != nullptr) {
+        frameRateMgr_->SetForceUpdateCallback([this](bool idleTimerExpired, bool forceUpdate) {
+            RSMainThread::Instance()->PostTask([this, idleTimerExpired, forceUpdate]() {
+                RS_TRACE_NAME_FMT("RSMainThread::TimerExpiredCallback Run idleTimerExpiredFlag: %s  forceUpdateFlag: %s",
+                    idleTimerExpired? "True":"False", forceUpdate? "True": "False");
+                RSMainThread::Instance()->SetForceUpdateUniRenderFlag(forceUpdate);
+                RSMainThread::Instance()->SetIdleTimerExpiredFlag(idleTimerExpired);
+                RS_TRACE_NAME_FMT("DVSyncIsOn: %d", this->rsVSyncDistributor_->IsDVsyncOn());
+                RSMainThread::Instance()->RequestNextVSync("ltpoForceUpdate");
+            });
         });
-    });
-    frameRateMgr_->Init(rsVSyncController_, appVSyncController_, vsyncGenerator_);
+        frameRateMgr_->Init(rsVSyncController_, appVSyncController_, vsyncGenerator_);
+    }
     SubscribeAppState();
     PrintCurrentStatus();
     RSLuminanceControl::Get().Init();
@@ -2804,7 +2806,10 @@ void RSMainThread::Animate(uint64_t timestamp)
         }
         totalAnimationSize += node->animationManager_.GetAnimationsSize();
         auto frameRateGetFunc = [this](const RSPropertyUnit unit, float velocity) -> int32_t {
-            return frameRateMgr_->GetExpectedFrameRate(unit, velocity);
+            if (frameRateMgr_ != nullptr) {
+                return frameRateMgr_->GetExpectedFrameRate(unit, velocity);
+            }
+            return 0;
         };
         node->animationManager_.SetRateDeciderEnable(isRateDeciderEnabled, frameRateGetFunc);
         auto [hasRunningAnimation, nodeNeedRequestNextVsync, nodeCalculateAnimationValue] =
diff --git a/rosen/modules/render_service/core/pipeline/rs_render_service_connection.cpp b/rosen/modules/render_service/core/pipeline/rs_render_service_connection.cpp
index 44433ad360..4b6aedfcea 100644
--- a/rosen/modules/render_service/core/pipeline/rs_render_service_connection.cpp
+++ b/rosen/modules/render_service/core/pipeline/rs_render_service_connection.cpp
@@ -178,7 +178,9 @@ void RSRenderServiceConnection::CleanAll(bool toDelete) noexcept
                 return;
             }
             RS_TRACE_NAME_FMT("CleanHgmEvent %d", connection->remotePid_);
-            connection->mainThread_->GetFrameRateMgr()->CleanVote(connection->remotePid_);
+            if (connection->mainThread_->GetFrameRateMgr() != nullptr) {
+                connection->mainThread_->GetFrameRateMgr()->CleanVote(connection->remotePid_);
+            }
         }).wait();
     mainThread_->ScheduleTask(
         [weakThis = wptr<RSRenderServiceConnection>(this)]() {
@@ -1742,6 +1744,10 @@ void RSRenderServiceConnection::NotifyLightFactorStatus(bool isSafe)
     if (!mainThread_) {
         return;
     }
+    if (mainThread_->GetFrameRateMgr() == nullptr) {
+        RS_LOGW("RSRenderServiceConnection::NotifyLightFactorStatus: frameRateMgr is nullptr.");
+        return;
+    }
     mainThread_->GetFrameRateMgr()->HandleLightFactorStatus(remotePid_, isSafe);
 }

五、社区代码修复

master分支和5.0.1Release分支已经对空指针问题进行修复,参考一下PR:

HGM切单线程 · Pull Request !13288 · OpenHarmony/graphic_graphic_2d - Gitee.com

修复HgmFrameRateManager空指针崩溃问题 · Pull Request !16834 · OpenHarmony/graphic_graphic_2d - Gitee.com

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐