From e03372d45f0fbbd4b45ef00136f02eaa7d8d0481 Mon Sep 17 00:00:00 2001 From: pollyzhang Date: Mon, 7 Mar 2022 18:50:28 +0800 Subject: [PATCH] fix(core): fix multi-context mode exception handling crash --- android/sdk/src/main/jni/src/bridge/entry.cc | 45 ++++++++++++------- .../sdk/src/main/jni/src/bridge/runtime.cc | 10 ++++- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/android/sdk/src/main/jni/src/bridge/entry.cc b/android/sdk/src/main/jni/src/bridge/entry.cc index 8d12f4978e6..066bb681bb9 100644 --- a/android/sdk/src/main/jni/src/bridge/entry.cc +++ b/android/sdk/src/main/jni/src/bridge/entry.cc @@ -90,9 +90,11 @@ static std::unordered_map, uint32_t>> reuse_engine_map; static std::mutex engine_mutex; -static const int64_t kDefaultEngineId = -1; -static const int64_t kDebuggerEngineId = -9999; -static const uint32_t kRuntimeSlotIndex = 0; +constexpr int64_t kDefaultEngineId = -1; +constexpr int64_t kDebuggerEngineId = -9999; +constexpr uint32_t kRuntimeSlotIndex = 0; +// -1 means single isolate multi-context mode +constexpr int32_t kReuseRuntimeId = -1; enum INIT_CB_STATE { RUN_SCRIPT_ERROR = -1, @@ -348,16 +350,23 @@ void HandleUncaughtJsError(v8::Local message, return; } - std::shared_ptr ctx = - std::static_pointer_cast( - runtime->GetScope()->GetContext()); - TDF_BASE_LOG(ERROR) << "HandleUncaughtJsError error desc = " + auto scope = runtime->GetScope(); + if (!scope) { + return; + } + auto context = scope->GetContext(); + if (!context) { + return; + } + std::shared_ptr ctx = std::static_pointer_cast(context); + TDF_BASE_LOG(ERROR) << "HandleUncaughtJsError, runtime_id = " + << runtime->GetId() + << ", desc = " << ctx->GetMsgDesc(message) << ", stack = " << ctx->GetStackInfo(message); ExceptionHandler::ReportJsException(runtime, ctx->GetMsgDesc(message), ctx->GetStackInfo(message)); - ctx->ThrowExceptionToJS( - std::make_shared(isolate, error)); + ctx->ThrowExceptionToJS(std::make_shared(isolate, error)); TDF_BASE_DLOG(INFO) << "HandleUncaughtJsError end"; } @@ -373,7 +382,7 @@ jlong InitInstance(JNIEnv* j_env, jobject j_vm_init_param) { TDF_BASE_LOG(INFO) << "InitInstance begin, j_single_thread_mode = " << static_cast(j_single_thread_mode) - << ", j_bridge_param_json = " + << ", j_enable_v8_serialization = " << static_cast(j_enable_v8_serialization) << ", j_is_dev_module = " << static_cast(j_is_dev_module) @@ -383,12 +392,19 @@ jlong InitInstance(JNIEnv* j_env, j_enable_v8_serialization, j_is_dev_module); int32_t runtime_id = runtime->GetId(); Runtime::Insert(runtime); - RegisterFunction vm_cb = [runtime_id](void* vm) { + int64_t group = j_group_id; + RegisterFunction vm_cb = [group, runtime_id](void* vm) { V8VM* v8_vm = reinterpret_cast(vm); v8::Isolate* isolate = v8_vm->isolate_; v8::HandleScope handle_scope(isolate); + if (group == kDefaultEngineId) { + TDF_BASE_LOG(INFO) << "isolate->SetData runtime_id = " << runtime_id; + isolate->SetData(kRuntimeSlotIndex, reinterpret_cast(runtime_id)); + } else { + TDF_BASE_LOG(INFO) << "isolate->SetData runtime_id = " << kReuseRuntimeId; + isolate->SetData(kRuntimeSlotIndex, reinterpret_cast(kReuseRuntimeId)); + } isolate->AddMessageListener(HandleUncaughtJsError); - isolate->SetData(kRuntimeSlotIndex, reinterpret_cast(runtime_id)); }; std::unique_ptr engine_cb_map = std::make_unique(); @@ -450,7 +466,6 @@ jlong InitInstance(JNIEnv* j_env, scope_cb_map->insert( std::make_pair(hippy::base::KScopeInitializedCBKey, scope_cb)); - int64_t group = j_group_id; std::shared_ptr param; if (j_vm_init_param) { param = std::make_shared(); @@ -491,10 +506,6 @@ jlong InitInstance(JNIEnv* j_env, engine = std::get>(it->second); runtime->SetEngine(engine); std::get(it->second) += 1; - std::shared_ptr v8_vm = std::static_pointer_cast(engine->GetVM()); - v8::Isolate* isolate = v8_vm->isolate_; - isolate->SetData(kRuntimeSlotIndex, reinterpret_cast(-1)); - // -1 means single isolate multi-context mode TDF_BASE_DLOG(INFO) << "engine cnt = " << std::get(it->second) << ", use_count = " << engine.use_count(); } else { diff --git a/android/sdk/src/main/jni/src/bridge/runtime.cc b/android/sdk/src/main/jni/src/bridge/runtime.cc index cdea8027a01..ef7d097e57b 100644 --- a/android/sdk/src/main/jni/src/bridge/runtime.cc +++ b/android/sdk/src/main/jni/src/bridge/runtime.cc @@ -25,6 +25,8 @@ #include #include +constexpr int32_t kReuseRuntimeId = -1; + using V8Ctx = hippy::napi::V8Ctx; static std::unordered_map> RuntimeMap; @@ -59,11 +61,15 @@ std::shared_ptr Runtime::Find(v8::Isolate *isolate) { } auto runtime_id = static_cast(reinterpret_cast(isolate->GetData(kRuntimeSlotIndex))); - if (runtime_id == -1) {// -1 means single isolate multi context mode + TDF_BASE_LOG(INFO) << "Runtime::Find runtime_id = " << runtime_id; + if (runtime_id == kReuseRuntimeId) {// -1 means single isolate multi context mode v8::Local context = isolate->GetCurrentContext(); std::lock_guard lock(mutex); for (const auto& p: RuntimeMap) { - std::shared_ptr scope = p.second->GetScope(); + auto scope = p.second->GetScope(); + if (!scope) { + continue; + } std::shared_ptr ctx = std::static_pointer_cast(scope->GetContext()); if (ctx->context_persistent_ == context) { return p.second;