修复napi_wrap发生异常,内存不释放问题

Signed-off-by: Lixiaoying25 <lixiaoying25@huawei.com>
This commit is contained in:
Lixiaoying25 2024-11-08 10:02:13 +08:00
parent d1bb5140ed
commit 84998280ca
8 changed files with 144 additions and 33 deletions

View File

@ -197,7 +197,11 @@ static napi_value NAPIMessageOption_JS_Constructor(napi_env env, napi_callback_i
waitTime = jsWaitTime;
}
auto messageOption = new MessageOption(flags, waitTime);
auto messageOption = new (std::nothrow) MessageOption(flags, waitTime);
if (messageOption == nullptr) {
ZLOGE(LOG_LABEL, "new MessageOption failed");
return nullptr;
}
// connect native message option to js thisVar
napi_status status = napi_wrap(
env, thisVar, messageOption,
@ -206,7 +210,11 @@ static napi_value NAPIMessageOption_JS_Constructor(napi_env env, napi_callback_i
delete (reinterpret_cast<MessageOption *>(data));
},
nullptr, nullptr);
NAPI_ASSERT(env, status == napi_ok, "wrap js MessageOption and native option failed");
if (status != napi_ok) {
ZLOGE(LOG_LABEL, "wrap js MessageOption and native option failed. status is %{public}d", status);
delete messageOption;
return nullptr;
}
return thisVar;
}

View File

@ -99,7 +99,8 @@ napi_value SendRequestAsync(napi_env env, sptr<IRemoteObject> target, uint32_t c
MessageOption &option, napi_value *argv)
{
napi_value result = nullptr;
SendRequestParam *sendRequestParam = new SendRequestParam {
napi_get_undefined(env, &result);
SendRequestParam *sendRequestParam = new (std::nothrow) SendRequestParam {
.target = target,
.code = code,
.data = data,
@ -116,6 +117,10 @@ napi_value SendRequestAsync(napi_env env, sptr<IRemoteObject> target, uint32_t c
.env = env,
.traceId = 0,
};
if (sendRequestParam == nullptr) {
ZLOGE(LOG_LABEL, "new sendRequestParam failed");
return result;
}
std::string remoteDescriptor = Str16ToStr8(target->GetInterfaceDescriptor());
if (!remoteDescriptor.empty()) {
@ -134,7 +139,7 @@ napi_value SendRequestAsync(napi_env env, sptr<IRemoteObject> target, uint32_t c
NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, ExecuteSendRequest,
SendRequestCbComplete, reinterpret_cast<void *>(sendRequestParam), &sendRequestParam->asyncWork));
NAPI_CALL(env, napi_queue_async_work(env, sendRequestParam->asyncWork));
napi_get_undefined(env, &result);
return result;
}
@ -145,7 +150,7 @@ napi_value SendRequestPromise(napi_env env, sptr<IRemoteObject> target, uint32_t
napi_deferred deferred = nullptr;
napi_value promise = nullptr;
napi_create_promise(env, &deferred, &promise);
SendRequestParam *sendRequestParam = new SendRequestParam {
SendRequestParam *sendRequestParam = new (std::nothrow) SendRequestParam {
.target = target,
.code = code,
.data = data,
@ -162,6 +167,11 @@ napi_value SendRequestPromise(napi_env env, sptr<IRemoteObject> target, uint32_t
.env = env,
.traceId = 0,
};
if (sendRequestParam == nullptr) {
ZLOGE(LOG_LABEL, "new sendRequestParam failed");
return nullptr;
}
std::string remoteDescriptor = Str16ToStr8(target->GetInterfaceDescriptor());
if (!remoteDescriptor.empty()) {
sendRequestParam->traceValue = remoteDescriptor + std::to_string(code);
@ -377,7 +387,12 @@ napi_value NAPI_RemoteProxy_addDeathRecipient(napi_env env, napi_callback_info i
return result;
}
sptr<NAPIDeathRecipient> nativeRecipient = new NAPIDeathRecipient(env, argv[ARGV_INDEX_0]);
sptr<NAPIDeathRecipient> nativeRecipient = new (std::nothrow) NAPIDeathRecipient(env, argv[ARGV_INDEX_0]);
if (nativeRecipient == nullptr) {
ZLOGE(LOG_LABEL, "new NAPIDeathRecipient failed");
napi_get_boolean(env, false, &result);
return result;
}
if (target->AddDeathRecipient(nativeRecipient)) {
NAPIDeathRecipientList *list = proxyHolder->list_;
if (list->Add(nativeRecipient)) {
@ -448,14 +463,19 @@ napi_value NAPI_RemoteProxy_registerDeathRecipient(napi_env env, napi_callback_i
return napiErr.ThrowError(env, errorDesc::PROXY_OR_REMOTE_OBJECT_INVALID_ERROR);
}
sptr<NAPIDeathRecipient> nativeRecipient = new NAPIDeathRecipient(env, argv[ARGV_INDEX_0]);
napi_value result = nullptr;
napi_get_undefined(env, &result);
sptr<NAPIDeathRecipient> nativeRecipient = new (std::nothrow) NAPIDeathRecipient(env, argv[ARGV_INDEX_0]);
if (nativeRecipient == nullptr) {
ZLOGE(LOG_LABEL, "new NAPIDeathRecipient failed");
return result;
}
bool ret = target->AddDeathRecipient(nativeRecipient);
if (ret) {
NAPIDeathRecipientList *list = proxyHolder->list_;
list->Add(nativeRecipient);
}
napi_value result = nullptr;
napi_get_undefined(env, &result);
ZLOGI(LOG_LABEL, "%{public}s", ret ? "succ" : "fail");
return result;
}
@ -692,7 +712,11 @@ napi_value RemoteProxy_JS_Constructor(napi_env env, napi_callback_info info)
napi_value thisVar = nullptr;
napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
// new napi proxy holder instance
auto proxyHolder = new NAPIRemoteProxyHolder();
auto proxyHolder = new (std::nothrow) NAPIRemoteProxyHolder();
if (proxyHolder == nullptr) {
ZLOGE(LOG_LABEL, "new NAPIRemoteProxyHolder failed");
return nullptr;
}
// connect native object to js thisVar
napi_status status = napi_wrap(
env, thisVar, proxyHolder,
@ -701,7 +725,11 @@ napi_value RemoteProxy_JS_Constructor(napi_env env, napi_callback_info info)
delete (reinterpret_cast<NAPIRemoteProxyHolder *>(data));
},
nullptr, nullptr);
NAPI_ASSERT(env, status == napi_ok, "wrap js RemoteProxy and native holder failed");
if (status != napi_ok) {
ZLOGE(LOG_LABEL, "wrap js RemoteProxy and native holder failed. status is %{public}d", status);
delete proxyHolder;
return nullptr;
}
return thisVar;
}

View File

@ -928,7 +928,7 @@ napi_value NAPIAshmem::Ashmem_JS_Constructor(napi_env env, napi_callback_info in
napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
NAPIAshmem *napiAshmem = nullptr;
if (argc == 0) {
napiAshmem = new NAPIAshmem();
napiAshmem = new (std::nothrow) NAPIAshmem();
} else {
NAPI_ASSERT(env, argc == 2, "requires 2 parameter");
napi_valuetype valueType = napi_null;
@ -950,7 +950,11 @@ napi_value NAPIAshmem::Ashmem_JS_Constructor(napi_env env, napi_callback_info in
// new napi Ashmem
sptr<Ashmem> nativeAshmem = Ashmem::CreateAshmem(ashmemName.c_str(), ashmemSize);
NAPI_ASSERT(env, nativeAshmem != nullptr, "invalid parameters");
napiAshmem = new NAPIAshmem(nativeAshmem);
napiAshmem = new (std::nothrow) NAPIAshmem(nativeAshmem);
}
if (napiAshmem == nullptr) {
ZLOGE(LOG_LABEL, "new NAPIAshmem failed");
return nullptr;
}
// connect native object to js thisVar
napi_status status = napi_wrap(
@ -960,7 +964,11 @@ napi_value NAPIAshmem::Ashmem_JS_Constructor(napi_env env, napi_callback_info in
delete (reinterpret_cast<NAPIAshmem *>(data));
},
nullptr, nullptr);
NAPI_ASSERT(env, status == napi_ok, "wrap js Ashmem and native holder failed");
if (status != napi_ok) {
ZLOGE(LOG_LABEL, "wrap js Ashmem and native holder failed. status is %{public}d", status);
delete napiAshmem;
return nullptr;
}
return thisVar;
}
} // namespace OHOS

View File

@ -1450,7 +1450,11 @@ napi_value NAPI_MessageParcel::JS_constructor(napi_env env, napi_callback_info i
NAPI_ASSERT(env, parcel != nullptr, "parcel is null");
}
// new native parcel object
auto messageParcel = new NAPI_MessageParcel(env, thisVar, parcel);
auto messageParcel = new (std::nothrow) NAPI_MessageParcel(env, thisVar, parcel);
if (messageParcel == nullptr) {
ZLOGE(LOG_LABEL, "new NAPIAshmem failed");
return nullptr;
}
// connect native object to js thisVar
status = napi_wrap(
env, thisVar, messageParcel,
@ -1461,7 +1465,11 @@ napi_value NAPI_MessageParcel::JS_constructor(napi_env env, napi_callback_info i
}
},
nullptr, nullptr);
NAPI_ASSERT(env, status == napi_ok, "napi wrap message parcel failed");
if (status != napi_ok) {
ZLOGE(LOG_LABEL, "napi wrap message parcel failed. status is %{public}d", status);
delete messageParcel;
return nullptr;
}
return thisVar;
}
} // namespace OHOS

View File

@ -2098,7 +2098,11 @@ napi_value NAPI_MessageSequence::JS_constructor(napi_env env, napi_callback_info
NAPI_ASSERT(env, parcel != nullptr, "parcel is null");
}
// new native parcel object
auto messageSequence = new NAPI_MessageSequence(env, thisVar, parcel);
auto messageSequence = new (std::nothrow) NAPI_MessageSequence(env, thisVar, parcel);
if (messageSequence == nullptr) {
ZLOGE(LOG_LABEL, "new NAPIAshmem failed");
return nullptr;
}
// connect native object to js thisVar
status = napi_wrap(
env, thisVar, messageSequence,
@ -2109,7 +2113,11 @@ napi_value NAPI_MessageSequence::JS_constructor(napi_env env, napi_callback_info
}
},
nullptr, nullptr);
NAPI_ASSERT(env, status == napi_ok, "napi wrap message parcel failed");
if (status != napi_ok) {
ZLOGE(LOG_LABEL, "napi wrap message parcel failed. status is %{public}d", status);
delete messageSequence;
return nullptr;
}
return thisVar;
}
} // namespace OHOS

View File

@ -465,10 +465,14 @@ static void RemoteObjectHolderRefCb(napi_env env, void *data, void *hint)
napi_get_uv_event_loop(workerEnv, &loop);
uv_work_t *work = new(std::nothrow) uv_work_t;
NAPI_ASSERT_RETURN_VOID(workerEnv, work != nullptr, "cb failed to new work");
OperateJsRefParam *param = new OperateJsRefParam {
OperateJsRefParam *param = new (std::nothrow) OperateJsRefParam {
.env = workerEnv,
.thisVarRef = ref
};
if (param == nullptr) {
ZLOGE(LOG_LABEL, "new OperateJsRefParam failed");
return;
}
work->data = reinterpret_cast<void *>(param);
int uvRet = uv_queue_work(loop, work, [](uv_work_t *work) {
ZLOGD(LOG_LABEL, "enter work pool.");
@ -566,11 +570,19 @@ napi_value RemoteObject_JS_Constructor(napi_env env, napi_callback_info info)
napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
NAPI_ASSERT(env, jsStringLength == bufferSize, "string length wrong");
std::string descriptor = stringValue;
auto holder = new NAPIRemoteObjectHolder(env, Str8ToStr16(descriptor), thisVar);
auto holder = new (std::nothrow) NAPIRemoteObjectHolder(env, Str8ToStr16(descriptor), thisVar);
if (holder == nullptr) {
ZLOGE(LOG_LABEL, "new NAPIRemoteObjectHolder failed");
return nullptr;
}
napi_coerce_to_native_binding_object(env, thisVar, RemoteObjectDetachCb, RemoteObjectAttachCb, holder, nullptr);
// connect native object to js thisVar
napi_status status = napi_wrap(env, thisVar, holder, RemoteObjectHolderFinalizeCb, nullptr, nullptr);
NAPI_ASSERT(env, status == napi_ok, "wrap js RemoteObject and native holder failed");
if (status != napi_ok) {
ZLOGE(LOG_LABEL, "wrap js RemoteObject and native holder failed. status is %{public}d", status);
delete holder;
return nullptr;
}
return thisVar;
}
@ -591,11 +603,14 @@ NAPIRemoteObject::NAPIRemoteObject(std::thread::id jsThreadId, napi_env env, nap
uv_work_t *work = new(std::nothrow) uv_work_t;
NAPI_ASSERT_RETURN_VOID(env_, work != nullptr, "create NAPIRemoteObject, new work failed");
std::shared_ptr<struct ThreadLockInfo> lockInfo = std::make_shared<struct ThreadLockInfo>();
OperateJsRefParam *param = new OperateJsRefParam {
OperateJsRefParam *param = new (std::nothrow) OperateJsRefParam {
.env = env_,
.thisVarRef = jsObjectRef,
.lockInfo = lockInfo.get()
};
if (param == nullptr) {
ZLOGE(LOG_LABEL, "new OperateJsRefParam failed");
}
work->data = reinterpret_cast<void *>(param);
int uvRet = uv_queue_work(loop, work, [](uv_work_t *work) {
@ -632,10 +647,13 @@ NAPIRemoteObject::~NAPIRemoteObject()
napi_get_uv_event_loop(env_, &loop);
uv_work_t *work = new(std::nothrow) uv_work_t;
NAPI_ASSERT_RETURN_VOID(env_, work != nullptr, "release NAPIRemoteObject, new work failed");
OperateJsRefParam *param = new OperateJsRefParam {
OperateJsRefParam *param = new (std::nothrow) OperateJsRefParam {
.env = env_,
.thisVarRef = thisVarRef_
};
if (param == nullptr) {
ZLOGE(LOG_LABEL, "new OperateJsRefParam failed");
}
work->data = reinterpret_cast<void *>(param);
int uvRet = uv_queue_work(loop, work, [](uv_work_t *work) {
ZLOGD(LOG_LABEL, "enter work pool.");
@ -695,7 +713,7 @@ int NAPIRemoteObject::OnRemoteRequest(uint32_t code, MessageParcel &data, Messag
ZLOGE(LOG_LABEL, "DUMP_TRANSACTION data size:%{public}zu", data.GetReadableBytes());
}
std::shared_ptr<struct ThreadLockInfo> lockInfo = std::make_shared<struct ThreadLockInfo>();
CallbackParam *param = new CallbackParam {
CallbackParam *param = new (std::nothrow) CallbackParam {
.env = env_,
.thisVarRef = thisVarRef_,
.code = code,
@ -705,6 +723,10 @@ int NAPIRemoteObject::OnRemoteRequest(uint32_t code, MessageParcel &data, Messag
.lockInfo = lockInfo.get(),
.result = 0
};
if (param == nullptr) {
ZLOGE(LOG_LABEL, "new CallbackParam failed");
return -1;
}
NAPI_RemoteObject_getCallingInfo(param->callingInfo);
ZLOGD(LOG_LABEL, "callingPid:%{public}u callingUid:%{public}u "
@ -878,7 +900,11 @@ napi_value NAPI_ohos_rpc_CreateJsRemoteObject(napi_env env, const sptr<IRemoteOb
return nullptr;
}
proxyHolder->object_ = target;
proxyHolder->list_ = new NAPIDeathRecipientList();
proxyHolder->list_ = new (std::nothrow) NAPIDeathRecipientList();
if (proxyHolder->list_ == nullptr) {
ZLOGE(LOG_LABEL, "new NAPIDeathRecipientList failed");
return nullptr;
}
return jsRemoteProxy;
}
@ -1072,7 +1098,11 @@ void StubExecuteSendRequest(napi_env env, SendRequestParam *param)
}
uv_loop_s *loop = nullptr;
napi_get_uv_event_loop(env, &loop);
uv_work_t *work = new uv_work_t;
uv_work_t *work = new (std::nothrow) uv_work_t;
if (work == nullptr) {
ZLOGE(LOG_LABEL, "new uv_work_t failed");
return;
}
work->data = reinterpret_cast<void *>(param);
uv_after_work_cb afterWorkCb = nullptr;
if (param->callback != nullptr) {
@ -1130,7 +1160,9 @@ napi_value StubSendRequestAsync(napi_env env, sptr<IRemoteObject> target, uint32
std::shared_ptr<MessageParcel> data, std::shared_ptr<MessageParcel> reply,
MessageOption &option, napi_value *argv)
{
SendRequestParam *sendRequestParam = new SendRequestParam {
napi_value result = nullptr;
napi_get_undefined(env, &result);
SendRequestParam *sendRequestParam = new (std::nothrow) SendRequestParam {
.target = target,
.code = code,
.data = data,
@ -1147,6 +1179,10 @@ napi_value StubSendRequestAsync(napi_env env, sptr<IRemoteObject> target, uint32
.env = env,
.traceId = 0,
};
if (sendRequestParam == nullptr) {
ZLOGE(LOG_LABEL, "new SendRequestParam failed");
return result;
}
if (target != nullptr) {
std::string remoteDescriptor = Str16ToStr8(target->GetObjectDescriptor());
if (!remoteDescriptor.empty()) {
@ -1162,8 +1198,7 @@ napi_value StubSendRequestAsync(napi_env env, sptr<IRemoteObject> target, uint32
napi_create_reference(env, argv[ARGV_INDEX_4], 1, &sendRequestParam->callback);
std::thread t(StubExecuteSendRequest, env, sendRequestParam);
t.detach();
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
@ -1174,7 +1209,7 @@ napi_value StubSendRequestPromise(napi_env env, sptr<IRemoteObject> target, uint
napi_deferred deferred = nullptr;
napi_value promise = nullptr;
NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
SendRequestParam *sendRequestParam = new SendRequestParam {
SendRequestParam *sendRequestParam = new (std::nothrow) SendRequestParam {
.target = target,
.code = code,
.data = data,
@ -1191,6 +1226,10 @@ napi_value StubSendRequestPromise(napi_env env, sptr<IRemoteObject> target, uint
.env = env,
.traceId = 0,
};
if (sendRequestParam == nullptr) {
ZLOGE(LOG_LABEL, "new SendRequestParam failed");
return nullptr;
}
if (target != nullptr) {
std::string remoteDescriptor = Str16ToStr8(target->GetObjectDescriptor());
if (!remoteDescriptor.empty()) {

View File

@ -59,10 +59,14 @@ void NAPIRemoteObjectHolder::DeleteJsObjectRefInUvWork()
ZLOGE(LOG_LABEL, "failed to new work");
return;
}
OperateJsRefParam *param = new OperateJsRefParam {
OperateJsRefParam *param = new (std::nothrow) OperateJsRefParam {
.env = env_,
.thisVarRef = jsObjectRef_
};
if (param == nullptr) {
ZLOGE(LOG_LABEL, "new OperateJsRefParam failed");
return;
}
work->data = reinterpret_cast<void *>(param);
int uvRet = uv_queue_work(loop, work, [](uv_work_t *work) {
ZLOGD(LOG_LABEL, "enter work pool.");
@ -125,7 +129,11 @@ sptr<IRemoteObject> NAPIRemoteObjectHolder::Get()
sptr<IRemoteObject> tmp = wptrCachedObject_.promote();
if (tmp == nullptr && env_ != nullptr) {
tmp = new NAPIRemoteObject(jsThreadId_, env_, jsObjectRef_, descriptor_);
tmp = new (std::nothrow) NAPIRemoteObject(jsThreadId_, env_, jsObjectRef_, descriptor_);
if (tmp == nullptr) {
ZLOGE(LOG_LABEL, "new NAPIRemoteObject failed");
return nullptr;
}
wptrCachedObject_ = tmp;
}
return tmp;

View File

@ -103,10 +103,14 @@ void NAPIDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
ZLOGE(LOG_LABEL, "failed to new uv_work_t");
return;
}
OnRemoteDiedParam *param = new OnRemoteDiedParam {
OnRemoteDiedParam *param = new (std::nothrow) OnRemoteDiedParam {
.env = env_,
.deathRecipient = this
};
if (param == nullptr) {
ZLOGE(LOG_LABEL, "new OnRemoteDiedParam failed");
return;
}
work->data = reinterpret_cast<void *>(param);
ZLOGI(LOG_LABEL, "start to queue");
int uvRet = uv_queue_work(loop, work, [](uv_work_t *work) {