当前位置: 首页 > article >正文

鸿蒙5.0版开发:分析CppCrash(进程崩溃)

在HarmonyOS 5.0中,CppCrash指的是C/C++运行时崩溃,这类崩溃可能由空指针异常、数组越界异常、栈溢出异常等原因引起。系统提供了基于posix信号机制的崩溃异常检测能力,能够生成详细的故障日志以辅助故障定位。本文将详细介绍如何分析CppCrash,包括异常检测能力、崩溃问题定位分析思路,以及具体的案例分析。

CppCrash异常检测能力

进程崩溃基于posix信号机制,目前主要支持对以下崩溃异常信号的处理:

信号值(signo)信号解释触发原因
4SIGILL非法指令进程执行了非法、格式错误、未知或特权指令
5SIGTRAP断点或陷阱异常异常或trap指令发生
6SIGABRT进程终止进程异常终止,通常为进程自身调用abort()函数
7SIGBUS非法内存访问进程访问了对齐或者不存在的物理地址
8SIGFPE浮点异常进程执行了错误的算术运算,如除数为0、浮点溢出等
11SIGSEGV无效内存访问进程访问了无效内存引用
16SIGSTKFLT栈错误处理器执行了错误的栈操作,如栈空时弹出、栈满时压入
31SIGSYS错误的系统调用系统调用时使用了错误或非法参数

以上部分故障信号,根据具体的场景还有二级分类(code)。

日志格式与获取

CppCrash故障根据报错场景可以分为运行态CppCrash故障和开发态CppCrash故障。在开发态下,DevEco Studio会收集CppCrash、App Freeze、JS Crash、System Freeze、ASan的崩溃日志到FaultLog下,开发者可以通过FaultLog的CppCrash日志、ASAN日志定位问题的具体原因。在运行态下,开发者需要提前开通崩溃服务,收集运行状态下的CppCrash。

基于崩溃栈定位行号

在应用开发场景中,对于应用自身的动态库,生成的cppcrash堆栈可以直接跳转到代码行处,支持Native栈帧和JS栈帧,无需开发者自行进行解行号操作。对于部分未能解析跳转到对应行号的栈帧,可以通过以下方式进行解析:

  1. DevEco Studio开发者环境下,支持调用栈直接跳转到对应行号:在应用开发场景,对于应用自身的动态库,生成的cppcrash堆栈可以直接跳转到代码行处,支持Native栈帧和JS栈帧,无需开发者自行进行解行号操作。

  2. 使用addr2line工具:对于未能直接跳转的栈帧,可以使用addr2line工具将地址转换为代码行号。例如,使用以下命令:

    $ addr2line -Cpie ./libcesfwk_core.z.so 000000000001c5a4
    /mnt/disk/jenkins/ci/workspace/zidane_system_pipeline_release/compile/component_code/out/baltimore/../../base/notification/common_event_service/frameworks/core/src/common_event_proxy.cpp:385

    这将帮助开发者快速定位到具体的代码行。

典型案例分析

锁范围不足导致的Crash问题

设备开关机压测时,崩溃在libcesfwk_core.z.so,崩溃栈如下:

Timestamp:1970-11-28 13:44:49.206
Pid:2906
Uid:10006
Process name:com.ohos.xxx
Reason:Signal:SIGSEGV(SEGV_MAPERR)@0x00492e6b7766746e
Fault thread Info:
Tid:2978, Name:com.ohos.system
#00 pc 000000000003fea8 /system/lib64/libipc_core.z.so(OHOS::PeerHolder::Remote()+12)
#01 pc 000000000001c5a4 /system/lib64/libcesfwk_core.z.so(OHOS::EventFwk::CommonEventProxy::SendRequest(OHOS::EventFwk::ICommonEvent::Message, OHOS::MessageParcel&, OHOS::MessageParcel&)+168)
#02 pc 000000000001cff8 /system/lib64/libcesfwk_core.z.so(OHOS::EventFwk::CommonEventProxy::SubscribeCommonEvent(OHOS::EventFwk::CommonEventSubscribeInfo const&, OHOS::sptr<OHOS::IRemoteObject> const&)+540)
#03 pc 0000000000016518 /system/lib64/libcesfwk_core.z.so(OHOS::EventFwk::CommonEvent::SubscribeCommonEvent(std::__1::shared_ptr<OHOS::EventFwk::CommonEventSubscriber> const&)+468)
#04 pc 0000000000012c20 /system/lib64/libcesfwk_innerkits.z.so(OHOS::EventFwk::CommonEventManager::SubscribeCommonEvent(std::__1::shared_ptr<OHOS::EventFwk::CommonEventSubscriber> const&)+56)
#05 pc 000000000003253c /system/lib64/module/libcommonevent.z.so
#06 pc 0000000000019808 /system/lib64/libace_napi.z.so(NativeAsyncWork::AsyncWorkCallback(uv_work_s*)+316)
#07 pc 000000000001156c /system/lib64/libuv.so
#08 pc 00000000000d02a0 /system/lib64/libc.so(__pthread_start(void*)+40)
#09 pc 0000000000072128 /system/lib64/libc.so(__start_thread+68)
...

根据Reason可知为野指针,根据#01定位到具体的代码行有:

$ addr2line -Cpie ./notification/common_event_service/libcesfwk_core.z.so 000000000001c5a4
/mnt/disk/jenkins/ci/workspace/zidane_system_pipeline_release/compile/component_code/out/baltimore/../../base/notification/common_event_service/frameworks/core/src/common_event_proxy.cpp:385

对应的代码如下所示:

bool CommonEventProxy::SendRequest(ICommonEvent::Message code, MessageParcel &data, MessageParcel &reply) {
    EVENT_LOGD("start");
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) {
        EVENT_LOGD("Remote is NULL, %{public}d", code);
    }
    MessageOption option(MessageOption::TF_SYNC);
    int32_t result = remote->SendRequest(static_cast<uint32_t>(code), data, reply, option);
    if (result != OHOS::NO_ERROR) {
        return false;
    }
    EVENT_LOGD("end");
    return true;
}

通过分析,可以发现remote指针可能为nullptr,导致后续的调用出现崩溃。

结语

通过本文的介绍,你应该对如何在HarmonyOS 5.0中分析CppCrash有了基本的了解。CppCrash分析是提升应用稳定性和用户体验的重要环节,合理利用日志分析和工具检测可以使你的应用更加健壮和易于维护。希望本文能够帮助你在开发过程中更好地分析和处理CppCrash问题。


http://www.kler.cn/a/394784.html

相关文章:

  • 【CSS】什么是BFC?
  • UAC2.0 speaker——同时支持 16bit,24bit 和 32bit
  • 【缺陷检测】Anomaly Detection via Reverse Distillation from One-Class Embedding
  • MFC工控项目实例二十九主对话框调用子对话框设定参数值
  • 编写红绿起爆线指标(附带源码下载)
  • 性能测试|JMeter接口与性能测试项目
  • 比大小王比赛
  • 云计算研究实训室建设方案
  • 【项目管理】MobaXterm终端工具(怎么连接服务器)
  • Spring Cloud生态圈
  • 深度学习-卷积神经网络CNN
  • 【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
  • stream学习
  • 决策树基本 CART Python手写实现
  • Elasticsearch(ES)简介
  • 零钱兑换(DP)
  • 基于SSM框架(Spring, Spring MVC, MyBatis)的矿场仓储管理系统的基础示例
  • 【GPTs】Gif-PT:DALL·E制作创意动图与精灵动画
  • 单片机 定时器实验 实验四
  • git配置远程仓库的认证信息
  • 吴恩达Prompt Engineering(2/9): Guidelines for Prompting
  • Perfetto中如何使用SQL语句
  • Excel根据条件动态索引单元格范围
  • PVE纵览-选择适合你的Proxmox VE存储方案:LVM、LVM-Thin、目录与ZFS对
  • docker镜像安装oracle11g
  • 互联网行业面对大数据时代新挑战如何实现数据高速传输