!749 fix ability acts crash when env destucted ahead

Merge pull request !749 from 马根堂/master
This commit is contained in:
openharmony_ci 2023-07-31 13:43:20 +00:00 committed by Gitee
commit e431c96ca5
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 50 additions and 1 deletions

View File

@ -32,6 +32,7 @@ public:
void Set(sptr<NAPIRemoteObject> object);
void attachLocalInterface(napi_value localInterface, std::string &descriptor);
napi_value queryLocalInterface(std::string &descriptor);
void CleanJsEnv();
void Lock()
{
mutex_.lock();

View File

@ -37,6 +37,8 @@ public:
int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
napi_ref GetJsObjectRef() const;
void ResetJsEnv();
private:
napi_env env_ = nullptr;
napi_value thisVar_ = nullptr;

View File

@ -113,6 +113,17 @@ static NativeValue *RemoteObjectAttachCb(NativeEngine *engine, void *value, void
return reinterpret_cast<NativeValue *>(jsRemoteObject);
}
static void OnEnvCleanUp(void *data)
{
if (data == nullptr) {
ZLOGE(LOG_LABEL, "data is null");
return;
}
NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(data);
// js env has been destrcted, clear saved env info, and check befor use it
holder->CleanJsEnv();
}
napi_value RemoteObject_JS_Constructor(napi_env env, napi_callback_info info)
{
// new napi remote object
@ -149,6 +160,9 @@ napi_value RemoteObject_JS_Constructor(napi_env env, napi_callback_info info)
ZLOGE(LOG_LABEL, "RemoteObject_JS_Constructor create native object failed");
return nullptr;
}
// register listener for env destruction
status = napi_add_env_cleanup_hook(env, OnEnvCleanUp, holder);
NAPI_ASSERT(env, status == napi_ok, "add cleanup hook failed");
return thisVar;
}
@ -164,7 +178,7 @@ NAPIRemoteObject::NAPIRemoteObject(napi_env env, napi_value thisVar, const std::
NAPIRemoteObject::~NAPIRemoteObject()
{
ZLOGI(LOG_LABEL, "NAPIRemoteObject Destructor");
if (thisVarRef_ != nullptr) {
if (thisVarRef_ != nullptr && env_ != nullptr) {
napi_status status = napi_delete_reference(env_, thisVarRef_);
NAPI_ASSERT_RETURN_VOID(env_, status == napi_ok, "failed to delete ref to js RemoteObject");
thisVarRef_ = nullptr;
@ -186,6 +200,12 @@ napi_ref NAPIRemoteObject::GetJsObjectRef() const
return thisVarRef_;
}
void NAPIRemoteObject::ResetJsEnv()
{
env_ = nullptr;
thisVarRef_ = nullptr;
}
void NAPI_RemoteObject_getCallingInfo(CallingInfo &newCallingInfoParam)
{
newCallingInfoParam.callingPid = IPCSkeleton::GetCallingPid();
@ -323,6 +343,10 @@ void NAPI_RemoteObject_resetOldCallingInfo(napi_env env, NAPI_CallingInfo &oldCa
int NAPIRemoteObject::OnJsRemoteRequest(CallbackParam *jsParam)
{
if (thisVarRef_ == nullptr || env_ == nullptr) {
ZLOGE(LOG_LABEL, "Js env has been destructed");
return ERR_UNKNOWN_REASON;
}
uv_loop_s *loop = nullptr;
napi_get_uv_event_loop(env_, &loop);

View File

@ -16,8 +16,12 @@
#include "napi_remote_object_holder.h"
#include <string_ex.h>
#include "ipc_debug.h"
#include "log_tags.h"
namespace OHOS {
static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC, "napi_remoteObject_holder" };
NAPIRemoteObjectHolder::NAPIRemoteObjectHolder(napi_env env, const std::u16string &descriptor)
: env_(env), descriptor_(descriptor), cachedObject_(nullptr), localInterfaceRef_(nullptr), attachCount_(1)
{}
@ -54,8 +58,22 @@ void NAPIRemoteObjectHolder::Set(sptr<NAPIRemoteObject> object)
cachedObject_ = object;
}
void NAPIRemoteObjectHolder::CleanJsEnv()
{
env_ = nullptr;
sptr<NAPIRemoteObject> object = cachedObject_;
if (object != nullptr) {
ZLOGI(LOG_LABEL, "reset env and napi_ref");
object->ResetJsEnv();
}
}
void NAPIRemoteObjectHolder::attachLocalInterface(napi_value localInterface, std::string &descriptor)
{
if (env_ == nullptr) {
ZLOGE(LOG_LABEL, "Js env has been destructed");
return;
}
if (localInterfaceRef_ != nullptr) {
napi_delete_reference(env_, localInterfaceRef_);
}
@ -65,6 +83,10 @@ void NAPIRemoteObjectHolder::attachLocalInterface(napi_value localInterface, std
napi_value NAPIRemoteObjectHolder::queryLocalInterface(std::string &descriptor)
{
if (env_ == nullptr) {
ZLOGE(LOG_LABEL, "Js env has been destructed");
return nullptr;
}
if (!descriptor_.empty() && strcmp(Str16ToStr8(descriptor_).c_str(), descriptor.c_str()) == 0) {
napi_value ret = nullptr;
napi_get_reference_value(env_, localInterfaceRef_, &ret);