From c30f99793c9837c02d8e5e3df39f53b23e8ec2ce Mon Sep 17 00:00:00 2001 From: wanglei Date: Thu, 21 Aug 2025 12:19:45 +0000 Subject: [PATCH] dlclose when arkweb upgrade Signed-off-by: wanglei --- interfaces/innerkits/include/appspawn.h | 1 + standard/appspawn_service.c | 67 ++++++++++++++++++- .../app_spawn_service_test.cpp | 16 ++--- 3 files changed, 71 insertions(+), 13 deletions(-) diff --git a/interfaces/innerkits/include/appspawn.h b/interfaces/innerkits/include/appspawn.h index 217363b0..e9feda93 100644 --- a/interfaces/innerkits/include/appspawn.h +++ b/interfaces/innerkits/include/appspawn.h @@ -123,6 +123,7 @@ typedef enum { MSG_UNINSTALL_DEBUG_HAP, MSG_LOCK_STATUS, MSG_OBSERVE_PROCESS_SIGNAL_STATUS, + MSG_UNLOAD_WEBLIB_IN_APPSPAWN, MSG_LOAD_WEBLIB_IN_APPSPAWN, MAX_TYPE_INVALID } AppSpawnMsgType; diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 5f9bceb9..274fe9a5 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -65,6 +65,11 @@ #define PIDFD_NONBLOCK O_NONBLOCK #endif +#if (defined(PRE_DLOPEN_ARKWEB_LIB) && !defined(ASAN_DETECTOR)) +#define MAX_DLCLOSE_COUNT 10 +#define LIB_ARKWEB_ENGINE "libarkweb_engine.so" +#endif + static void WaitChildTimeout(const TimerHandle taskHandle, void *context); static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context); static void WaitChildDied(pid_t pid); @@ -1751,6 +1756,58 @@ APPSPAWN_STATIC void ProcessObserveProcessSignalMsg(AppSpawnConnection *connecti DeleteAppSpawnMsg(&message); } +#if (defined(PRE_DLOPEN_ARKWEB_LIB) && !defined(ASAN_DETECTOR)) +static bool IsNWebLibLoaded(Dl_namespace dlns) +{ + void* handler = dlopen_ns(&dlns, LIB_ARKWEB_ENGINE, RTLD_NOW | RTLD_NOLOAD); + if (handler) { + dlclose(handler); + return true; + } + return false; +} +#endif + +static void ProcessSpawnDlcloseMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message) +{ + AppSpawnMsg* msg = &message->msgHeader; + APPSPAWN_LOGI("Recv ProcessSpawnDlcloseMsg message header magic: 0x%{public}x type: %{public}u" + "id: %{public}u len: %{public}u processName: %{public}s", + msg->magic, + msg->msgType, + msg->msgId, + msg->msgLen, + msg->processName); + +#if (defined(PRE_DLOPEN_ARKWEB_LIB) && !defined(ASAN_DETECTOR)) + Dl_namespace dlns; + if (dlns_get("nweb_ns", &dlns) != 0) { + APPSPAWN_LOGI("Failed to get nweb_ns"); + SendResponse(connection, msg, 0, 0); + return; + } + + void* webEngineHandle = dlopen_ns(&dlns, LIB_ARKWEB_ENGINE, RTLD_NOW | RTLD_NOLOAD); + if (!webEngineHandle) { + APPSPAWN_LOGE("FAILED to find %{public}s in appspawn %{public}s", LIB_ARKWEB_ENGINE, dlerror()); + SendResponse(connection, msg, 0, 0); + return; + } + + int cnt = MAX_DLCLOSE_COUNT; + do { + cnt--; + dlclose(webEngineHandle); + } while (cnt > 0 && IsNWebLibLoaded(dlns)); + + if (cnt == 0 && IsNWebLibLoaded(dlns)) { + SendResponse(connection, msg, -1, 0); + return; + } +#endif + SendResponse(connection, msg, 0, 0); +} + static void ProcessSpawnDlopenMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message) { AppSpawnMsg* msg = &message->msgHeader; @@ -1783,12 +1840,12 @@ static void ProcessSpawnDlopenMsg(AppSpawnConnection *connection, AppSpawnMsgNod dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); } - void* webEngineHandle = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_GLOBAL); + void* webEngineHandle = dlopen_ns(&dlns, LIB_ARKWEB_ENGINE, RTLD_NOW | RTLD_GLOBAL); if (!webEngineHandle) { - APPSPAWN_LOGE("FAILED to dlopen libarkweb_engine.so in appspawn %{public}s", dlerror()); + APPSPAWN_LOGE("FAILED to dlopen %{public}s in appspawn %{public}s", LIB_ARKWEB_ENGINE, dlerror()); SendResponse(connection, msg, -1, 0); } else { - APPSPAWN_LOGI("SUCCESS to dlopen libarkweb_engine.so in appspawn"); + APPSPAWN_LOGI("SUCCESS to dlopen %{public}s in appspawn", LIB_ARKWEB_ENGINE); SendResponse(connection, msg, 0, 0); #ifndef OHOS_LITE ReclaimFileCache(); @@ -1859,6 +1916,10 @@ static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *mess case MSG_OBSERVE_PROCESS_SIGNAL_STATUS: ProcessObserveProcessSignalMsg(connection, message); break; + case MSG_UNLOAD_WEBLIB_IN_APPSPAWN: + ProcessSpawnDlcloseMsg(connection, message); + DeleteAppSpawnMsg(&message); + break; case MSG_LOAD_WEBLIB_IN_APPSPAWN: ProcessSpawnDlopenMsg(connection, message); DeleteAppSpawnMsg(&message); diff --git a/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp index f0441dcd..a8f86701 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp @@ -1187,7 +1187,7 @@ HWTEST_F(AppSpawnServiceTest, App_Spawn_ConvertEnvValue_001, TestSize.Level0) } /** - * @brief 向appspawn发送MSG_LOAD_WEBLIB_IN_APPSPAWN类型的消息,传入arkweb包名 + * @brief 向appspawn发送MSG_LOAD_WEBLIB_IN_APPSPAWN类型的消息,传入任意包名 * */ HWTEST_F(AppSpawnServiceTest, App_Spawn_MSG_LOAD_WEBLIB_IN_APPSPAWN_001, TestSize.Level0) @@ -1198,12 +1198,8 @@ HWTEST_F(AppSpawnServiceTest, App_Spawn_MSG_LOAD_WEBLIB_IN_APPSPAWN_001, TestSiz ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME); - char bundleName[64] = {0}; - ret = GetParameter("persist.arkwebcore.package_name", "", bundleName, 64); - APPSPAWN_CHECK(ret == 0, break, "Failed to get arkweb bundleName"); - AppSpawnReqMsgHandle reqHandle; - ret = AppSpawnReqMsgCreate(MSG_LOAD_WEBLIB_IN_APPSPAWN, bundleName, &reqHandle); + ret = AppSpawnReqMsgCreate(MSG_LOAD_WEBLIB_IN_APPSPAWN, "com.example.myapplication", &reqHandle); AppSpawnResult result = {}; ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result); APPSPAWN_CHECK(ret == 0, break, "Failed to send MSG_LOAD_WEBLIB_IN_APPSPAWN, ret %{public}d", ret); @@ -1214,10 +1210,10 @@ HWTEST_F(AppSpawnServiceTest, App_Spawn_MSG_LOAD_WEBLIB_IN_APPSPAWN_001, TestSiz } /** - * @brief 向appspawn发送MSG_LOAD_WEBLIB_IN_APPSPAWN类型的消息,传入空字符串 + * @brief 向appspawn发送MSG_UNLOAD_WEBLIB_IN_APPSPAWN类型的消息,传入任意包名 * */ -HWTEST_F(AppSpawnServiceTest, App_Spawn_MSG_LOAD_WEBLIB_IN_APPSPAWN_002, TestSize.Level0) +HWTEST_F(AppSpawnServiceTest, App_Spawn_MSG_UNLOAD_WEBLIB_IN_APPSPAWN_001, TestSize.Level0) { int ret = 0; AppSpawnClientHandle clientHandle = nullptr; @@ -1226,10 +1222,10 @@ HWTEST_F(AppSpawnServiceTest, App_Spawn_MSG_LOAD_WEBLIB_IN_APPSPAWN_002, TestSiz APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME); AppSpawnReqMsgHandle reqHandle; - ret = AppSpawnReqMsgCreate(MSG_LOAD_WEBLIB_IN_APPSPAWN, "", &reqHandle); + ret = AppSpawnReqMsgCreate(MSG_UNLOAD_WEBLIB_IN_APPSPAWN, "com.example.myapplication", &reqHandle); AppSpawnResult result = {}; ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result); - APPSPAWN_CHECK(ret == 0, break, "Failed to send MSG_LOAD_WEBLIB_IN_APPSPAWN, ret %{public}d", ret); + APPSPAWN_CHECK(ret == 0, break, "Failed to send MSG_UNLOAD_WEBLIB_IN_APPSPAWN, ret %{public}d", ret); } while (0); AppSpawnClientDestroy(clientHandle); -- Gitee