长稳测试的时候,偶现CppCrash崩溃,每次的崩溃栈不同,复现的场景不明确。查看多个崩溃日志都有出现SIGSEGV(SEGV_MAPERR)@0x0000000000000000 probably caused by NULL pointer dereference报错,其中之一的报错信息如下:
- Generated by HiviewDFX@OpenHarmony
- ================================================================
- Device info:HUAWEI Mate 60 Pro
- Build info:ALN-AL00 5.0.0.150(SP8C00E150R4P30log)
- Fingerprint:xxxxxxxxx
- Module name:com.example.application
- Version:2.8.5
- VersionCode:30
- PreInstalled:No
- Foreground:No
- Timestamp:2025-04-30 14:17:03.643
- Pid:42378
- Uid:20020210
- Process name:com.example.application
- Process life time:18446744073709405886s
- Reason:Signal:SIGSEGV(SEGV_MAPERR)@0x0000000000000007 probably caused by NULL pointer dereference
- Fault thread info:
- Tid:42378, Name:m.example.application
- #00 pc 0000000000135dc8 /data/storage/el1/bundle/libs/arm64/libnet.so(91a0f067f914ed44654e1191fccc295e60882cb0)
- #01 pc 0000000000135d68 /data/storage/el1/bundle/libs/arm64/libnet.so(91a0f067f914ed44654e1191fccc295e60882cb0)
- #02 pc 00000000001397c0 /data/storage/el1/bundle/libs/arm64/libnet.so(91a0f067f914ed44654e1191fccc295e60882cb0)
- #03 pc 000000000012b0d8 /data/storage/el1/bundle/libs/arm64/libnet.so(91a0f067f914ed44654e1191fccc295e60882cb0)
- #04 pc 000000000012aa78 /data/storage/el1/bundle/libs/arm64/libnet.so(doCallback(napi_env__*, napi_status, void*)+1584)(91a0f067f914ed44654e1191fccc295e60882cb0)
- #05 pc 00000000000704f4 /system/lib64/platformsdk/libace_napi.z.so(NativeSafeAsyncWork::ProcessAsyncHandle()+596)(85e70f1f5cf0e81468ec141fc2f4922c)
- #06 pc 0000000000016de4 /system/lib64/platformsdk/libuv.so(uv__async_io+352)(81fe2b78ed1df8447a6c4e51c5f644e2)
- #07 pc 0000000000028840 /system/lib64/platformsdk/libuv.so(uv__io_poll+1016)(81fe2b78ed1df8447a6c4e51c5f644e2)
- #08 pc 00000000000173cc /system/lib64/platformsdk/libuv.so(uv_run+408)(81fe2b78ed1df8447a6c4e51c5f644e2)
- #09 pc 000000000007f250 /system/lib64/platformsdk/libruntime.z.so(OHOS::AbilityRuntime::OHOSLoopHandler::OnTriggered()+140)(17e438b05b67ccb9c7eb96e54ed833e5)
- #10 pc 0000000000020430 /system/lib64/chipset-pub-sdk/libeventhandler.z.so(770d0cd78402a5ad1ced37fad50c5707)
- #11 pc 000000000001bdb4 /system/lib64/chipset-pub-sdk/libeventhandler.z.so(OHOS::AppExecFwk::EventHandler::DistributeEvent(std::__h::unique_ptr<OHOS::AppExecFwk::InnerEvent, void (*)(OHOS::AppExecFwk::InnerEvent*)> const&)+1140)(770d0cd78402a5ad1ced37fad50c5707)
CppCrash(进程崩溃)是指C/C++运行时崩溃。目前主要支持崩溃异常信号SIGBUS、SIGFPE、SIGSEGV、SIGSTKFLT、SIGSYS、SIGILL、SIGTRAP、SIGABRT的处理。可以通过FaultLogger模块获取崩溃日志。
崩溃日志报错中空指针解引用NULL pointer dereference表现形式一般为:
定位该类型问题一般尝试以下几种方法:
- pc 0000000000135dc8 /data/storage/el1/bundle/libs/arm64/libnet.so(91a0f067f914ed44654e1191fccc295e60882cb0)
- #01 pc 0000000000135d68 /data/storage/el1/bundle/libs/arm64/libnet.so(91a0f067f914ed44654e1191fccc295e60882cb0)
- #02 pc 00000000001397c0 /data/storage/el1/bundle/libs/arm64/libnet.so(91a0f067f914ed44654e1191fccc295e60882cb0)
- #03 pc 000000000012b0d8 /data/storage/el1/bundle/libs/arm64/libnet.so(91a0f067f914ed44654e1191fccc295e60882cb0)
- #04 pc 000000000012aa78 /data/storage/el1/bundle/libs/arm64/libnet.so(doCallback(napi_env__*, napi_status, void*)+1584)(91a0f067f914ed44654e1191fccc295e60882cb0)
- void doCallback(napi_env env, napi_status status, void *data) {
- if (env == nullptr || data == nullptr) {
- LOGE("Invalid env or data");
- return;
- }
- // ...
- }
- {
- "apiType": "stageMode",
- "buildOption": {
- "externalNativeOptions": {
- "path": "./src/main/cpp/CMakeLists.txt",
- "arguments": ["-DCMAKE_BUILD_TYPE=RelWithDebInfo"],
- "cppFlags": "",
- }
- },
- // ...
- }
- "buildOptionSet": [
- {
- "name": "debug",
- "arkOptions": {
- "obfuscation": {
- "ruleOptions": {
- "enable": false,
- "files": [
- "./obfuscation-rules.txt"
- ]
- }
- }
- },
- "nativeLib": {
- "debugSymbol": {
- "strip": false,
- "exclude": []
- }
- }
- },
- ],
- [root@ncn4b-partnervectorservice-33-83-97 arm64-v8a]# file libnet.so
- libnet.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=9d075a569e007bc6e4ea25f2f96be548724b4aef, with debug_info, not stripped

- llvm-addr2line -Cipe LocalPath/libnet.so 000000000012aa78
- napi_call_function(env, nullptr, callback, 1, &returnValue, &tempValue);
说明是napi_call_function在调用ArkTS函数指针的时候,回调函数指针可能被其他线程释放了才导致的踩空。
但是从上层传下来的函数制造者却没有创建强引用napi_ref保留。所以当GC回收了ArkTS的回调函数资源后,使用该ArkTS回调函数可能在Native执行napi_call_function前就已经是空指针了,最后导致空指针解引用。
- // 异步工作Native流程
- static napi_value StartAsyncWork(napi_env env, napi_callback_info info)
- {
- // 从模块数据中获取函数引用
- ModuleData* moduleData = nullptr;
- napi_get_instance_data(env, (void**)&moduleData);
-
- if (moduleData == nullptr || moduleData->arktsFuncRef == nullptr) {
- napi_throw_error(env, nullptr, "请先注册ArkTS函数");
- return nullptr;
- }
-
- // 创建新的工作数据
- AsyncWorkData* workData = new AsyncWorkData();
- workData->env = env;
-
- // 为异步工作创建新的函数引用
- napi_value arktsFunc;
- if (napi_get_reference_value(env, moduleData->arktsFuncRef, &arktsFunc) != napi_ok) {
- delete workData;
- napi_throw_error(env, nullptr, "获取注册的函数失败");
- return nullptr;
- }
-
- // 创建新的引用给异步工作使用
- if (napi_create_reference(env, arktsFunc, 1, &workData->arktsFuncRef) != napi_ok) {
- delete workData;
- napi_throw_error(env, nullptr, "为异步工作创建函数引用失败");
- return nullptr;
- }
-
- // 创建异步工作
- napi_async_work asyncWork;
- napi_value workName;
- napi_create_string_utf8(env, "MyProc", NAPI_AUTO_LENGTH, &workName);
-
- if (napi_create_async_work(env, nullptr, workName, ExecuteWork, doCallback, workData, &asyncWork) != napi_ok) {
- napi_delete_reference(env, workData->arktsFuncRef);
- delete workData;
- napi_throw_error(env, nullptr, "创建异步工作失败");
- return nullptr;
- }
-
- // 排队执行异步工作
- if (napi_queue_async_work(env, asyncWork) != napi_ok) {
- napi_delete_async_work(env, asyncWork);
- napi_delete_reference(env, workData->arktsFuncRef);
- delete workData;
- napi_throw_error(env, nullptr, "排队异步工作失败");
- return nullptr;
- }
-
- OH_LOG_INFO(LOG_APP, "异步工作已启动");
-
- napi_value result;
- napi_get_undefined(env, &result);
- return result;
- }
- // 异步工作完成回调(在主线程/JS线程中执行)
- void doCallback(napi_env env, napi_status status, void* data)
- {
- AsyncWorkData* workData = static_cast<AsyncWorkData*>(data);
-
- if (status != napi_ok || workData == nullptr) {
- OH_LOG_ERROR(LOG_APP, "异步工作完成回调出错");
- return;
- }
-
- // 安全地调用ArkTS函数
- if (workData->arktsFuncRef != nullptr) {
- napi_handle_scope scope;
- napi_status status;
-
- // 创建作用域
- if (napi_open_handle_scope(env, &scope) != napi_ok) {
- OH_LOG_ERROR(LOG_APP, "打开handle scope失败");
- // 清理工作数据
- if (workData->arktsFuncRef != nullptr) {
- napi_delete_reference(env, workData->arktsFuncRef);
- }
- delete workData;
- return;
- }
-
- napi_value arktsFunc;
- status = napi_get_reference_value(env, workData->arktsFuncRef, &arktsFunc);
- if (status == napi_ok && arktsFunc != nullptr) {
- // 创建要传递给ArkTS函数的参数,本例为字符串
- napi_value argv[1];
- napi_create_string_utf8(env, workData->resultMessage.c_str(), NAPI_AUTO_LENGTH, &argv[0]);
- // 调用ArkTS函数
- napi_value global;
- napi_get_global(env, &global);
-
- napi_value result;
- if (napi_call_function(env, global, arktsFunc, 1, argv, &result) == napi_ok) {
- OH_LOG_INFO(LOG_APP, "成功调用ArkTS回调函数,消息: %{public}s",
- workData->resultMessage.c_str());
- } else {
- OH_LOG_ERROR(LOG_APP, "调用ArkTS函数失败");
- }
- } else {
- OH_LOG_ERROR(LOG_APP, "获取ArkTS函数引用失败");
- }
- // 关闭作用域
- napi_close_handle_scope(env, scope);
- }
- }
完整示例参考如下:
- # the minimum version of CMake.
- cmake_minimum_required(VERSION 3.5.0)
- project(SQI202505101216105442012)
-
- set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
-
- if(DEFINED PACKAGE_FIND_FILE)
- include(${PACKAGE_FIND_FILE})
- endif()
- include_directories(${NATIVERENDER_ROOT_PATH}
- ${NATIVERENDER_ROOT_PATH}/include)
-
- add_library(entry SHARED napi_init.cpp)
- target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libuv.so)
- /*
- * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
- */
-
- #include "napi/native_api.h"
- #include <thread>
- #include "hilog/log.h"
- #include <uv.h>
-
- #undef LOG_DOMAIN
- #undef LOG_TAG
- #define LOG_DOMAIN 0x3200 // 全局domain宏,标识业务领域
- #define LOG_TAG "MY_TAG" // 全局tag宏,标识模块日志tag
-
- // 异步工作数据结构
- struct AsyncWorkData {
- napi_env env = nullptr;
- napi_ref arktsFuncRef = nullptr; // 保存ArkTS函数的引用
- std::string resultMessage; // 要传递给ArkTS的结果
- };
-
- // 模块全局数据
- struct ModuleData {
- napi_ref arktsFuncRef = nullptr;
- };
-
- // 异步工作执行函数(在工作线程中执行)
- void ExecuteWork(napi_env env, void* data)
- {
- AsyncWorkData* workData = static_cast<AsyncWorkData*>(data);
-
- // 模拟一些耗时操作
- for (int i = 0; i < 3; i++) {
- OH_LOG_INFO(LOG_APP, "耗时异步流程执行中... %{public}d", i);
- // 模拟工作耗时操作
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
- }
-
- // 准备要传递给ArkTS的消息
- workData->resultMessage = "来自Native层的异步完成消息,时间戳: " +
- std::to_string(uv_hrtime() / 1000000);
- }
-
- // 异步工作完成回调(在主线程/JS线程中执行)
- void doCallback(napi_env env, napi_status status, void* data)
- {
- AsyncWorkData* workData = static_cast<AsyncWorkData*>(data);
-
- if (status != napi_ok || workData == nullptr) {
- OH_LOG_ERROR(LOG_APP, "异步工作完成回调出错");
- return;
- }
-
- // 安全地调用ArkTS函数
- if (workData->arktsFuncRef != nullptr) {
- napi_handle_scope scope;
- napi_status status;
-
- // 创建作用域
- if (napi_open_handle_scope(env, &scope) != napi_ok) {
- OH_LOG_ERROR(LOG_APP, "打开handle scope失败");
- // 清理工作数据
- if (workData->arktsFuncRef != nullptr) {
- napi_delete_reference(env, workData->arktsFuncRef);
- }
- delete workData;
- return;
- }
-
- napi_value arktsFunc;
- status = napi_get_reference_value(env, workData->arktsFuncRef, &arktsFunc);
- if (status == napi_ok && arktsFunc != nullptr) {
- // 创建要传递给ArkTS函数的参数,本例为字符串
- napi_value argv[1];
- napi_create_string_utf8(env, workData->resultMessage.c_str(), NAPI_AUTO_LENGTH, &argv[0]);
- // 调用ArkTS函数
- napi_value global;
- napi_get_global(env, &global);
-
- napi_value result;
- if (napi_call_function(env, global, arktsFunc, 1, argv, &result) == napi_ok) {
- OH_LOG_INFO(LOG_APP, "成功调用ArkTS回调函数,消息: %{public}s",
- workData->resultMessage.c_str());
- } else {
- OH_LOG_ERROR(LOG_APP, "调用ArkTS函数失败");
- }
- } else {
- OH_LOG_ERROR(LOG_APP, "获取ArkTS函数引用失败");
- }
- // 关闭作用域
- napi_close_handle_scope(env, scope);
- }
- }
-
- // 注册ArkTS函数的Native方法
- static napi_value RegisterArkTSFunction(napi_env env, napi_callback_info info)
- {
- size_t argc = 1;
- napi_value args[1];
- napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
-
- if (argc < 1) {
- napi_throw_error(env, nullptr, "需要传入ArkTS函数作为参数");
- return nullptr;
- }
-
- napi_valuetype valuetype;
- napi_typeof(env, args[0], &valuetype);
- if (valuetype != napi_function) {
- napi_throw_type_error(env, nullptr, "参数必须是一个函数");
- return nullptr;
- }
-
- // 获取模块数据
- ModuleData* moduleData = nullptr;
- napi_get_instance_data(env, (void**)&moduleData);
- if (moduleData == nullptr) {
- moduleData = new ModuleData();
- napi_set_instance_data(env, moduleData, [](napi_env env, void* data, void* hint) {
- ModuleData* moduleData = static_cast<ModuleData*>(data);
- if (moduleData && moduleData->arktsFuncRef) {
- napi_delete_reference(env, moduleData->arktsFuncRef);
- }
- delete moduleData;
- }, nullptr);
- } else {
- // 如果已经注册过函数,先清理旧的引用
- if (moduleData->arktsFuncRef != nullptr) {
- napi_delete_reference(env, moduleData->arktsFuncRef);
- moduleData->arktsFuncRef = nullptr;
- }
- }
-
- // 创建对ArkTS函数的强引用,防止被GC
- napi_status status = napi_create_reference(env, args[0], 1, &moduleData->arktsFuncRef);
- if (status != napi_ok) {
- napi_throw_error(env, nullptr, "创建函数引用失败");
- return nullptr;
- }
-
- OH_LOG_INFO(LOG_APP, "ArkTS函数注册成功");
-
- napi_value result;
- napi_get_undefined(env, &result);
- return result;
- }
-
- // 异步工作Native流程
- static napi_value StartAsyncWork(napi_env env, napi_callback_info info)
- {
- // 从模块数据中获取函数引用
- ModuleData* moduleData = nullptr;
- napi_get_instance_data(env, (void**)&moduleData);
-
- if (moduleData == nullptr || moduleData->arktsFuncRef == nullptr) {
- napi_throw_error(env, nullptr, "请先注册ArkTS函数");
- return nullptr;
- }
-
- // 创建新的工作数据
- AsyncWorkData* workData = new AsyncWorkData();
- workData->env = env;
-
- // 为异步工作创建新的函数引用
- napi_value arktsFunc;
- if (napi_get_reference_value(env, moduleData->arktsFuncRef, &arktsFunc) != napi_ok) {
- delete workData;
- napi_throw_error(env, nullptr, "获取注册的函数失败");
- return nullptr;
- }
-
- // 创建新的引用给异步工作使用
- if (napi_create_reference(env, arktsFunc, 1, &workData->arktsFuncRef) != napi_ok) {
- delete workData;
- napi_throw_error(env, nullptr, "为异步工作创建函数引用失败");
- return nullptr;
- }
-
- // 创建异步工作
- napi_async_work asyncWork;
- napi_value workName;
- napi_create_string_utf8(env, "MyProc", NAPI_AUTO_LENGTH, &workName);
-
- if (napi_create_async_work(env, nullptr, workName, ExecuteWork, doCallback, workData, &asyncWork) != napi_ok) {
- napi_delete_reference(env, workData->arktsFuncRef);
- delete workData;
- napi_throw_error(env, nullptr, "创建异步工作失败");
- return nullptr;
- }
-
- // 排队执行异步工作
- if (napi_queue_async_work(env, asyncWork) != napi_ok) {
- napi_delete_async_work(env, asyncWork);
- napi_delete_reference(env, workData->arktsFuncRef);
- delete workData;
- napi_throw_error(env, nullptr, "排队异步工作失败");
- return nullptr;
- }
-
- OH_LOG_INFO(LOG_APP, "异步工作已启动");
-
- napi_value result;
- napi_get_undefined(env, &result);
- return result;
- }
-
- EXTERN_C_START
- static napi_value Init(napi_env env, napi_value exports)
- {
- napi_property_descriptor desc[] = {
- { "registerArkTSFunction", nullptr, RegisterArkTSFunction, nullptr, nullptr, nullptr, napi_default, nullptr },
- { "startAsyncWork", nullptr, StartAsyncWork, nullptr, nullptr, nullptr, napi_default, nullptr }
- };
- napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
- return exports;
- }
- EXTERN_C_END
-
- static napi_module demoModule = {
- .nm_version = 1,
- .nm_flags = 0,
- .nm_filename = nullptr,
- .nm_register_func = Init,
- .nm_modname = "entry",
- .nm_priv = ((void*)0),
- .reserved = { 0 },
- };
-
- extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
- {
- napi_module_register(&demoModule);
- }
- export const registerArkTSFunction: (callback: (message: string) => void) => void;
- export const startAsyncWork: () => void;
- import testNapi from 'libentry.so';
-
- // 要传递给Native层的回调函数
- function myArkTSFunction(message: string): void {
- console.info('ArkTS收到Native消息: ' + message);
- }
-
- @Entry
- @Component
- struct Index {
- @State message: string = 'Hello World';
-
- aboutToAppear(): void {
- this.registerCallbackToNative();
- }
-
- build() {
- Row() {
- Column() {
- Text(this.message)
- .fontSize(20)
- .margin(10)
-
- Button('触发异步工作')
- .onClick(() => {
- this.triggerAsyncWork();
- this.message = '异步工作已触发';
- })
- .margin(10)
- }
- .width('100%');
- }
- .height('100%');
- }
-
- // 注册回调函数到Native层
- registerCallbackToNative(): void {
- try {
- testNapi.registerArkTSFunction(myArkTSFunction);
- console.info('ArkTS函数注册成功');
- } catch (error) {
- console.error('注册ArkTS函数失败: ' + error);
- }
- }
-
- // 触发Native层的异步工作
- triggerAsyncWork(): void {
- try {
- testNapi.startAsyncWork();
- console.info('已触发Native异步工作');
- } catch (error) {
- console.error('触发异步工作失败: ' + error);
- }
- }
- }