HarmonyOS鸿蒙Next中napi_reject_deferred方法调用崩溃

HarmonyOS鸿蒙Next中napi_reject_deferred方法调用崩溃 有几个崩溃发生在napi_reject_deferred内部。有人帮忙看下napi_reject_deferred什么情况下会出现这个崩溃?

堆栈:

Thread #00 pc 000000000002a548 [Unknown] 
#01 pc 0000000000053498 /system/lib64/platformsdk/libace_napi.so(napi_reject_deferred+120)(9cacfe19b71604ddfc0c17c9bb332f9d) 
#02 pc 0000000000243a68 /data/storage/el1/bundle/libs/arm64/libmobius.so(mbs::rpc_wrap::CallRpc(napi_env*, napi_callback_info*)::$_2::operator()(napi_value*, napi_value*) const+68)(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#03 pc 0000000000246fe0 /data/storage/el1/bundle/libs/arm64/libmobius.so(mbs::rpc_wrap::CallRpc(napi_env*, napi_callback_info*)::$_1::operator()(std::__n1::shared_ptr<mbs::common::Error> const&) const::'lambda'(napi_env*)::operator()() const+60)(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#04 pc 0000000000246f94 /data/storage/el1/bundle/libs/arm64/libmobius.so(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#05 pc 0000000000246f40 /data/storage/el1/bundle/libs/arm64/libmobius.so(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#06 pc 0000000000246f14 /data/storage/el1/bundle/libs/arm64/libmobius.so(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#07 pc 0000000000245f4c /data/storage/el1/bundle/libs/arm64/libmobius.so(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#08 pc 000000000027c73c /data/storage/el1/bundle/libs/arm64/libmobius.so(std::__n1::__function::__value_func<void (napi_env*)>::operator()[abi:v15004](napi_env*&&) const+72)(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#09 pc 000000000027c608 /data/storage/el1/bundle/libs/arm64/libmobius.so(std::__n1::function<void (napi_env*)>::operator()(napi_env*) const+48)(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#10 pc 000000000027c4b0 /data/storage/el1/bundle/libs/arm64/libmobius.so(mbs::napi_utils::RunInJSThread(napi_env*, std::__n1::function<void (napi_env*)>)::$_1::operator()(uv_work_s*, int) const+108)(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#11 pc 000000000027c434 /data/storage/el1/bundle/libs/arm64/libmobius.so(mbs::napi_utils::RunInJSThread(napi_env*, std::__n1::function<void (napi_env*)>)::$_1::__invoke(uv_work_s*, int)+32)(7915438c2e8d2585bc6bdf103cdefd37d2feabe8) 
#12 pc 0000000000075754 /system/lib64/platformsdk/libruntime.z.so(d67c4e574b7f5537fc0849b4913e509a) 
#13 pc 0000000000015324 /system/lib64/chipset-pub-sdk/libeventhandler.z.so(OHOS::AppExecFwk::EventHandler::DistributeEvent(std::__h::unique_ptr<OHOS::AppExecFwk::InnerEvent, void (*)(OHOS::AppExecFwk::InnerEvent*)> const&)+1156)(60c5781acd06586105f5ec8f9bb541a2) 
#14 pc 0000000000023f78 /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*)>&)+340)(60c5781acd06586105f5ec8f9bb541a2) 
#15 pc 0000000000023850 /system/lib64/chipset-pub-sdk/libeventhandler.z.so(OHOS::AppExecFwk::(anonymous namespace)::EventRunnerImpl::Run()+872)(60c5781acd06586105f5ec8f9bb541a2) 
#16 pc 0000000000026628 /system/lib64/chipset-pub-sdk/libeventhandler.z.so(OHOS::AppExecFwk::EventRunner::Run()+284)(60c5781acd06586105f5ec8f9bb541a2) 
#17 pc 00000000000a5434 /system/lib64/platformsdk/libappkit_native.z.so(OHOS::AppExecFwk::MainThread::Start()+764)(bc92cb3aa05b6350d030d7cd0372d145) 
#18 pc 0000000000004880 /system/lib64/appspawn/appspawn/libappspawn_ace.z.so(RunChildProcessor(AppSpawnContent*, AppSpawnClient*)+216)(54c10df710b78807df93802e499c1360) 
#19 pc 0000000000008788 /system/bin/appspawn(AppSpawnChild+404)(2247d7781e56021c70b6932ca9b37c80) 
#20 pc 00000000000084c8 /system/bin/appspawn(AppSpawnProcessMsg+636)(2247d7781e56021c70b6932ca9b37c80) 
#21 pc 000000000000f93c /system/bin/appspawn(ProcessSpawnReqMsg+228)(2247d7781e56021c70b6932ca9b37c80) 
#22 pc 000000000000f1ec /system/bin/appspawn(OnReceiveRequest+172)(2247d7781e56021c70b6932ca9b37c80) 
#23 pc 0000000000017c9c /system/lib64/chipset-pub-sdk/libbegetutil.z.so(HandleRecvMsg_+260)(2b7e903481b55508f91f36331a364f37) 
#24 pc 00000000000177bc /system/lib64/chipset-pub-sdk/libbegetutil.z.so(HandleStreamEvent_+168)(2b7e903481b55508f91f36331a364f37) 
#25 pc 0000000000014ee0 /system/lib64/chipset-pub-sdk/libbegetutil.z.so(ProcessEvent+108)(2b7e903481b55508f91f36331a364f37) 
#26 pc 0000000000014aa0 /system/lib64/chipset-pub-sdk/libbegetutil.z.so(RunLoop_+356)(2b7e903481b55508f91f36331a364f37) 
#27 pc 000000000000d384 /system/bin/appspawn(AppSpawnRun+136)(2247d7781e56021c70b6932ca9b37c80) 
#28 pc 000000000000ace8 /system/bin/appspawn(main+708)(2247d7781e56021c70b6932ca9b37c80) 
#29 pc 00000000000a6018 /system/lib/ld-musl-aarch64.so.1(libc_start_main_stage2+64)(280a864f87964e8138dabec5ed31180a)

最后两行调用代码:

// #02 pc 0000000000243a68
auto [deferred, promise] = napi_utils::CreatePromise(env);
auto done = [env, deferred = deferred](napi_value error, napi_value response) {
    if (error) { 
        napi_reject_deferred(env, deferred, error);  // 崩溃发生在这里 
    } else { 
        napi_resolve_deferred(env, deferred, response); 
    }
};

// #03 pc 0000000000246fe0
auto failure_callback = [done, uri,env](const ErrorSharedPtr& error) {
    napi_utils::RunInJSThread(env, [done, error](napi_env env) {
        napi_value js_error = error_wrap::CreateJsError(env,error);
        done(js_error, nullptr);
        
        // 这里调用了上面的lambda方法
    });
};

有人帮忙看看napi_reject_deferred内部什么情况下会出现这种错误?


更多关于HarmonyOS鸿蒙Next中napi_reject_deferred方法调用崩溃的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复
  1. napi_env变量创建的napi_value变量不能跨线程创建。
  2. napi_env变量创建的napi_value变量不能跨线程使用。
  3. napi_env变量创建的napi_value不能超出作用域使用,如,在一个函数中创建了napi_value,在该函数的作用域外使用napi_value。
  4. 从IR上的代码片段,最少违反了第三条的要求。

请参考:https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-cppcrash-guidance-V5


里面介绍了“napi_value超出NAPI框架的scope”

请参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs-V5/faqs-ndk-development-V5?catalogVersion=V5


里面也有一些说明介绍,如“native主线程外的其他线程通常不能直接使用需要napi_env、napi_value的NAPI函数,线程安全函数可以在其他线程中被调用,并回到主线程中执行”等等。

如果可以话,需要您提供完整的crash日志附上,日志不完整,会影响问题定位分析,日志中有需要信息都能帮助分析定位的,如版本号,栈信息,hilog日志等等。谢谢!

参考链接:https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-cppcrash-guidance-V5#section331112351790

//调用add前会open scope //Add函数结束后框架层会close scope 系统内部会加默认的。

可以参考这个图片的说明:https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-cppcrash-guidance-V5#section331112351790

更多关于HarmonyOS鸿蒙Next中napi_reject_deferred方法调用崩溃的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,napi_reject_deferred方法用于在异步操作失败时拒绝一个延迟的Promise对象。如果调用该方法时发生崩溃,可能的原因包括:

  1. 无效的napi_deferred对象:传递给napi_reject_deferrednapi_deferred对象可能无效或已被释放。确保该对象是通过napi_create_promise正确创建的,并且在调用napi_reject_deferred时仍然有效。

  2. 无效的napi_value对象:传递给napi_reject_deferrednapi_value对象可能无效或类型不正确。确保该对象是一个有效的JavaScript值,并且类型符合预期。

  3. 线程安全问题napi_reject_deferred必须在创建napi_deferred对象的同一线程中调用。如果在不同线程中调用,可能会导致未定义行为或崩溃。

  4. 内存管理问题:如果napi_reject_deferred调用前后存在内存泄漏或内存损坏问题,可能会导致崩溃。确保在调用该方法前后进行适当的内存管理。

  5. API版本不匹配:使用的napi库版本可能与HarmonyOS鸿蒙Next的版本不兼容。确保使用的napi库版本与系统版本匹配。

  6. 系统bug:在极少数情况下,崩溃可能是由于系统本身的bug引起的。这种情况下,需要等待华为修复相关问题。

排查崩溃问题时,建议使用调试工具(如gdblldb)捕获崩溃时的堆栈信息,以便更准确地定位问题根源。

在HarmonyOS鸿蒙Next中,napi_reject_deferred方法调用崩溃可能由以下原因导致:

  1. 无效的deferred对象:确保传递给napi_reject_deferreddeferred对象是有效的,且未被提前释放或重复使用。

  2. error对象无效:检查传递给napi_reject_deferrederror对象是否有效,确保它已正确创建且未被释放。

  3. 线程安全问题:确保napi_reject_deferred在正确的线程上下文中调用,避免多线程竞争条件。

  4. 内存问题:检查是否存在内存泄漏或越界访问,使用工具如Valgrind进行排查。

建议逐步排查以上问题,确保deferrederror对象的有效性,并在调试模式下运行以捕获更多信息。

回到顶部