1570af302Sopenharmony_ci/* 2570af302Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4570af302Sopenharmony_ci * you may not use this file except in compliance with the License. 5570af302Sopenharmony_ci * You may obtain a copy of the License at 6570af302Sopenharmony_ci * 7570af302Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8570af302Sopenharmony_ci * 9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12570af302Sopenharmony_ci * See the License for the specific language governing permissions and 13570af302Sopenharmony_ci * limitations under the License. 14570af302Sopenharmony_ci */ 15570af302Sopenharmony_ci 16570af302Sopenharmony_ci/* 17570af302Sopenharmony_ciThe hook mode has 3 kinds which can be set by command "param set": 18570af302Sopenharmony_ci(1) param set libc.hook_mode "startup:\"prog1 \"" 19570af302Sopenharmony_ci(2) param set libc.hook_mode startup:program1 20570af302Sopenharmony_ci(3) param set libc.hook_mode step 21570af302Sopenharmony_ci(4) param set libc.hook_mode direct 22570af302Sopenharmony_ci 23570af302Sopenharmony_ciCase 1 represents "startup" mode, and the hooked process is "prog1 ", 24570af302Sopenharmony_ciwhich loads hooking shared library when the program starts up. 25570af302Sopenharmony_ciThe path is added with two quotation marks because a quotation mark is a special charcter, 26570af302Sopenharmony_ciwhich need be escaped. 27570af302Sopenharmony_ci(2) is similar with (1), but no escaped character, so quotation marks doesn't need. 28570af302Sopenharmony_ci(3) represents "step" mode, which loads hooking shared library by some steps. 29570af302Sopenharmony_ci(4) represetnt "direct" mode, which loads hooking shared library by a step. 30570af302Sopenharmony_ci*/ 31570af302Sopenharmony_ci 32570af302Sopenharmony_ci#ifdef HOOK_ENABLE 33570af302Sopenharmony_ci#include <unistd.h> 34570af302Sopenharmony_ci#include <signal.h> 35570af302Sopenharmony_ci#include "musl_malloc_dispatch_table.h" 36570af302Sopenharmony_ci#include "musl_malloc.h" 37570af302Sopenharmony_ci#include "musl_preinit_common.h" 38570af302Sopenharmony_ci#ifdef OHOS_ENABLE_PARAMETER 39570af302Sopenharmony_ci#include "sys_param.h" 40570af302Sopenharmony_ci#endif 41570af302Sopenharmony_ci#include <pthread.h> 42570af302Sopenharmony_ci#include <stdlib.h> 43570af302Sopenharmony_ci#include <limits.h> 44570af302Sopenharmony_ci#include <dlfcn.h> 45570af302Sopenharmony_ci#include <errno.h> 46570af302Sopenharmony_ci#include <stdatomic.h> 47570af302Sopenharmony_ci#include <ctype.h> 48570af302Sopenharmony_ci#include <assert.h> 49570af302Sopenharmony_ci#include <string.h> 50570af302Sopenharmony_ci#include <malloc.h> 51570af302Sopenharmony_ci#include "musl_log.h" 52570af302Sopenharmony_ci 53570af302Sopenharmony_civoid* ohos_malloc_hook_init_function(size_t bytes); 54570af302Sopenharmony_civoid default_memtrace(void* addr, size_t size, const char* tag, bool is_using) {} 55570af302Sopenharmony_ci 56570af302Sopenharmony_cistatic struct MallocDispatchType __ohos_malloc_hook_init_dispatch = { 57570af302Sopenharmony_ci .malloc = ohos_malloc_hook_init_function, 58570af302Sopenharmony_ci .free = MuslFunc(free), 59570af302Sopenharmony_ci .mmap = MuslMalloc(mmap), 60570af302Sopenharmony_ci .munmap = MuslMalloc(munmap), 61570af302Sopenharmony_ci .calloc = MuslFunc(calloc), 62570af302Sopenharmony_ci .realloc = MuslFunc(realloc), 63570af302Sopenharmony_ci .prctl = MuslMalloc(prctl), 64570af302Sopenharmony_ci .malloc_usable_size = MuslMalloc(malloc_usable_size), 65570af302Sopenharmony_ci .memtrace = default_memtrace, 66570af302Sopenharmony_ci .aligned_alloc = MuslMalloc(aligned_alloc), 67570af302Sopenharmony_ci}; 68570af302Sopenharmony_ci#define MAX_SYM_NAME_SIZE 1000 69570af302Sopenharmony_ci#define MAX_PROC_NAME_SIZE 256 70570af302Sopenharmony_ci#define ADDR_NATIVE_ENABLE (1<<4) 71570af302Sopenharmony_ci#define ADDR_NATIVE_DISABLE (1<<5) 72570af302Sopenharmony_ci#define ADDR_NATIVE_SAVE (1<<6) 73570af302Sopenharmony_ci#define ADDR_NATIVE_CLEAR (1<<7) 74570af302Sopenharmony_cistatic char *__malloc_hook_shared_lib = "libnative_hook.z.so"; 75570af302Sopenharmony_cistatic char *__malloc_hook_function_prefix = "ohos_malloc_hook"; 76570af302Sopenharmony_civolatile atomic_llong ohos_malloc_hook_shared_library; 77570af302Sopenharmony_cistatic char *kMemTrackSharedLib = "libmemleak_tracker.so"; 78570af302Sopenharmony_cistatic char *kMemTrackPrefix = "track"; 79570af302Sopenharmony_cistatic char *kMemTrackPropertyEnable = "const.hiview.memleak_tracker.enable"; 80570af302Sopenharmony_cistatic char *kMemTrackSign = "true"; 81570af302Sopenharmony_cibool checkLoadMallocMemTrack = false; 82570af302Sopenharmony_ciunsigned int memLeakTypeContent = 0; 83570af302Sopenharmony_civolatile atomic_llong memleak_ever_shared_library_handle; 84570af302Sopenharmony_civolatile atomic_llong ohos_malloc_ever_shared_library_handle; 85570af302Sopenharmony_civoid* function_of_shared_lib[LAST_FUNCTION]; 86570af302Sopenharmony_civoid* function_of_ohos_malloc_shared_lib[LAST_FUNCTION]; 87570af302Sopenharmony_civoid* function_of_memleak_shared_lib[LAST_FUNCTION]; 88570af302Sopenharmony_cistatic enum EnumHookMode __hook_mode = STEP_HOOK_MODE; 89570af302Sopenharmony_cistatic void __uninstal_malloc_hook(); 90570af302Sopenharmony_ci 91570af302Sopenharmony_cistatic void get_native_hook_param(char *buf, unsigned int buf_len) 92570af302Sopenharmony_ci{ 93570af302Sopenharmony_ci#ifdef OHOS_ENABLE_PARAMETER 94570af302Sopenharmony_ci CachedHandle handle = CachedParameterCreate(MUSL_HOOK_PARAM_NAME, ""); 95570af302Sopenharmony_ci const char *value = CachedParameterGet(handle); 96570af302Sopenharmony_ci if (value != NULL) { 97570af302Sopenharmony_ci size_t size = strlen(value); 98570af302Sopenharmony_ci if (size > 0 && size < buf_len) { 99570af302Sopenharmony_ci strcpy(buf, value); 100570af302Sopenharmony_ci } 101570af302Sopenharmony_ci } 102570af302Sopenharmony_ci CachedParameterDestroy(handle); 103570af302Sopenharmony_ci#else 104570af302Sopenharmony_ci return; 105570af302Sopenharmony_ci#endif 106570af302Sopenharmony_ci} 107570af302Sopenharmony_ci 108570af302Sopenharmony_cistatic void get_memleak_hook_param() 109570af302Sopenharmony_ci{ 110570af302Sopenharmony_ci#ifdef OHOS_ENABLE_PARAMETER 111570af302Sopenharmony_ci CachedHandle handle = CachedParameterCreate(kMemTrackPropertyEnable, "false"); 112570af302Sopenharmony_ci const char *value = CachedParameterGet(handle); 113570af302Sopenharmony_ci if (value != NULL && strncmp(value, kMemTrackSign, strlen(kMemTrackSign)) == 0) { 114570af302Sopenharmony_ci checkLoadMallocMemTrack = true; 115570af302Sopenharmony_ci } 116570af302Sopenharmony_ci CachedParameterDestroy(handle); 117570af302Sopenharmony_ci#else 118570af302Sopenharmony_ci return; 119570af302Sopenharmony_ci#endif 120570af302Sopenharmony_ci} 121570af302Sopenharmony_ci 122570af302Sopenharmony_cistatic int parse_hook_variable(enum EnumHookMode* mode, char* path, int size) 123570af302Sopenharmony_ci{ 124570af302Sopenharmony_ci if (!mode || !path || size <= 0) { 125570af302Sopenharmony_ci return -1; 126570af302Sopenharmony_ci } 127570af302Sopenharmony_ci char hook_param_value[OHOS_PARAM_MAX_SIZE + 1] = {0}; 128570af302Sopenharmony_ci unsigned int len = OHOS_PARAM_MAX_SIZE; 129570af302Sopenharmony_ci get_native_hook_param(hook_param_value, len); 130570af302Sopenharmony_ci if (hook_param_value[0] == '\0') { 131570af302Sopenharmony_ci *mode = STEP_HOOK_MODE; 132570af302Sopenharmony_ci path[0] = '\0'; 133570af302Sopenharmony_ci } else { 134570af302Sopenharmony_ci char* ptr = hook_param_value; 135570af302Sopenharmony_ci while (*ptr && *ptr != ':') { 136570af302Sopenharmony_ci ++ptr; 137570af302Sopenharmony_ci } 138570af302Sopenharmony_ci 139570af302Sopenharmony_ci if (*ptr == ':') { 140570af302Sopenharmony_ci *ptr = '\0'; 141570af302Sopenharmony_ci ++ptr; 142570af302Sopenharmony_ci } 143570af302Sopenharmony_ci 144570af302Sopenharmony_ci if (strcmp(hook_param_value, "startup") == 0) { 145570af302Sopenharmony_ci *mode = STARTUP_HOOK_MODE; 146570af302Sopenharmony_ci } else if (strcmp(hook_param_value, "direct") == 0) { 147570af302Sopenharmony_ci *mode = DIRECT_HOOK_MODE; 148570af302Sopenharmony_ci } else if (strcmp(hook_param_value, "step") == 0) { 149570af302Sopenharmony_ci *mode = STEP_HOOK_MODE; 150570af302Sopenharmony_ci } else { 151570af302Sopenharmony_ci *mode = STEP_HOOK_MODE; 152570af302Sopenharmony_ci } 153570af302Sopenharmony_ci if (*mode == STARTUP_HOOK_MODE) { 154570af302Sopenharmony_ci if (*ptr == '\"') { 155570af302Sopenharmony_ci ++ptr; 156570af302Sopenharmony_ci int idx = 0; 157570af302Sopenharmony_ci while (idx < size - 1 && *ptr && *ptr != '\"') { 158570af302Sopenharmony_ci path[idx++] = *ptr++; 159570af302Sopenharmony_ci } 160570af302Sopenharmony_ci path[idx] = '\0'; 161570af302Sopenharmony_ci } else { 162570af302Sopenharmony_ci int idx = 0; 163570af302Sopenharmony_ci while (idx < size - 1 && *ptr) { 164570af302Sopenharmony_ci path[idx++] = *ptr++; 165570af302Sopenharmony_ci } 166570af302Sopenharmony_ci path[idx] = '\0'; 167570af302Sopenharmony_ci } 168570af302Sopenharmony_ci } 169570af302Sopenharmony_ci } 170570af302Sopenharmony_ci return 0; 171570af302Sopenharmony_ci} 172570af302Sopenharmony_ci 173570af302Sopenharmony_cistatic bool get_proc_name(pid_t pid, char *buf, unsigned int buf_len) 174570af302Sopenharmony_ci{ 175570af302Sopenharmony_ci if (pid <= 0) { 176570af302Sopenharmony_ci return false; 177570af302Sopenharmony_ci } 178570af302Sopenharmony_ci char target_file[FILE_NAME_MAX_SIZE] = {0}; 179570af302Sopenharmony_ci (void)snprintf(target_file, sizeof(target_file), "/proc/%d/cmdline", pid); 180570af302Sopenharmony_ci FILE *f = fopen(target_file, "r"); 181570af302Sopenharmony_ci if (f == NULL) { 182570af302Sopenharmony_ci return false; 183570af302Sopenharmony_ci } 184570af302Sopenharmony_ci if (fgets(buf, buf_len, f) == NULL) { 185570af302Sopenharmony_ci (void)fclose(f); 186570af302Sopenharmony_ci return false; 187570af302Sopenharmony_ci } 188570af302Sopenharmony_ci (void)fclose(f); 189570af302Sopenharmony_ci return true; 190570af302Sopenharmony_ci} 191570af302Sopenharmony_ci 192570af302Sopenharmony_cistatic bool init_malloc_function(void* malloc_shared_library_handler, MallocMallocType* func, const char* prefix) 193570af302Sopenharmony_ci{ 194570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 195570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "malloc"); 196570af302Sopenharmony_ci *func = (MallocMallocType)(dlsym(malloc_shared_library_handler, symbol)); 197570af302Sopenharmony_ci if (*func == NULL) { 198570af302Sopenharmony_ci return false; 199570af302Sopenharmony_ci } 200570af302Sopenharmony_ci return true; 201570af302Sopenharmony_ci} 202570af302Sopenharmony_ci 203570af302Sopenharmony_cistatic bool init_free_function(void* malloc_shared_library_handler, MallocFreeType* func, const char* prefix) 204570af302Sopenharmony_ci{ 205570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 206570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "free"); 207570af302Sopenharmony_ci *func = (MallocFreeType)(dlsym(malloc_shared_library_handler, symbol)); 208570af302Sopenharmony_ci if (*func == NULL) { 209570af302Sopenharmony_ci return false; 210570af302Sopenharmony_ci } 211570af302Sopenharmony_ci return true; 212570af302Sopenharmony_ci} 213570af302Sopenharmony_ci 214570af302Sopenharmony_cistatic bool init_mmap_function(void* malloc_shared_library_handler, MallocMmapType* func, const char* prefix) 215570af302Sopenharmony_ci{ 216570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 217570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "mmap"); 218570af302Sopenharmony_ci *func = (MallocMmapType)(dlsym(malloc_shared_library_handler, symbol)); 219570af302Sopenharmony_ci if (*func == NULL) { 220570af302Sopenharmony_ci return false; 221570af302Sopenharmony_ci } 222570af302Sopenharmony_ci return true; 223570af302Sopenharmony_ci} 224570af302Sopenharmony_ci 225570af302Sopenharmony_cistatic bool init_munmap_function(void* malloc_shared_library_handler, MallocMunmapType* func, const char* prefix) 226570af302Sopenharmony_ci{ 227570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 228570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "munmap"); 229570af302Sopenharmony_ci *func = (MallocMunmapType)(dlsym(malloc_shared_library_handler, symbol)); 230570af302Sopenharmony_ci if (*func == NULL) { 231570af302Sopenharmony_ci return false; 232570af302Sopenharmony_ci } 233570af302Sopenharmony_ci return true; 234570af302Sopenharmony_ci} 235570af302Sopenharmony_ci 236570af302Sopenharmony_cistatic bool init_memtrace_function(void* malloc_shared_library_handler, MemTrace* func, const char* prefix) 237570af302Sopenharmony_ci{ 238570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 239570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "memtrace"); 240570af302Sopenharmony_ci *func = (MemTrace)(dlsym(malloc_shared_library_handler, symbol)); 241570af302Sopenharmony_ci if (*func == NULL) { 242570af302Sopenharmony_ci return false; 243570af302Sopenharmony_ci } 244570af302Sopenharmony_ci return true; 245570af302Sopenharmony_ci} 246570af302Sopenharmony_ci 247570af302Sopenharmony_cistatic bool init_calloc_function(void* malloc_shared_library_handler, MallocCallocType* func, const char* prefix) 248570af302Sopenharmony_ci{ 249570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 250570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "calloc"); 251570af302Sopenharmony_ci *func = (MallocCallocType)(dlsym(malloc_shared_library_handler, symbol)); 252570af302Sopenharmony_ci if (*func == NULL) { 253570af302Sopenharmony_ci return false; 254570af302Sopenharmony_ci } 255570af302Sopenharmony_ci return true; 256570af302Sopenharmony_ci} 257570af302Sopenharmony_ci 258570af302Sopenharmony_cistatic bool init_realloc_function(void* malloc_shared_library_handler, MallocReallocType* func, const char* prefix) 259570af302Sopenharmony_ci{ 260570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 261570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "realloc"); 262570af302Sopenharmony_ci *func = (MallocReallocType)(dlsym(malloc_shared_library_handler, symbol)); 263570af302Sopenharmony_ci if (*func == NULL) { 264570af302Sopenharmony_ci return false; 265570af302Sopenharmony_ci } 266570af302Sopenharmony_ci return true; 267570af302Sopenharmony_ci} 268570af302Sopenharmony_ci 269570af302Sopenharmony_cistatic bool init_malloc_usable_size_function(void* malloc_shared_library_handler, MallocMallocUsableSizeType* func, const char* prefix) 270570af302Sopenharmony_ci{ 271570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 272570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "malloc_usable_size"); 273570af302Sopenharmony_ci *func = (MallocMallocUsableSizeType)(dlsym(malloc_shared_library_handler, symbol)); 274570af302Sopenharmony_ci if (*func == NULL) { 275570af302Sopenharmony_ci return false; 276570af302Sopenharmony_ci } 277570af302Sopenharmony_ci return true; 278570af302Sopenharmony_ci} 279570af302Sopenharmony_ci 280570af302Sopenharmony_cistatic bool init_prctl_function(void* malloc_shared_library_handler, MallocPrctlType* func, const char* prefix) 281570af302Sopenharmony_ci{ 282570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 283570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "prctl"); 284570af302Sopenharmony_ci *func = (MallocPrctlType)(dlsym(malloc_shared_library_handler, symbol)); 285570af302Sopenharmony_ci if (*func == NULL) { 286570af302Sopenharmony_ci return false; 287570af302Sopenharmony_ci } 288570af302Sopenharmony_ci return true; 289570af302Sopenharmony_ci} 290570af302Sopenharmony_ci 291570af302Sopenharmony_cistatic bool init_aligned_alloc_function(void* malloc_shared_library_handler, MallocAlignedAllocType* func, const char* prefix) 292570af302Sopenharmony_ci{ 293570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 294570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "aligned_alloc"); 295570af302Sopenharmony_ci *func = (MallocAlignedAllocType)(dlsym(malloc_shared_library_handler, symbol)); 296570af302Sopenharmony_ci if (*func == NULL) { 297570af302Sopenharmony_ci return false; 298570af302Sopenharmony_ci } 299570af302Sopenharmony_ci return true; 300570af302Sopenharmony_ci} 301570af302Sopenharmony_ci 302570af302Sopenharmony_ci#ifdef USE_JEMALLOC_RECYCLE_FUNC 303570af302Sopenharmony_ciextern int je_reclaim_cache(); 304570af302Sopenharmony_cistatic void handle_recycle_cache() 305570af302Sopenharmony_ci{ 306570af302Sopenharmony_ci int ret; 307570af302Sopenharmony_ci ret = je_reclaim_cache(); 308570af302Sopenharmony_ci MUSL_LOGD("je_reclaim_cache result=%{public}d", ret); 309570af302Sopenharmony_ci} 310570af302Sopenharmony_ci 311570af302Sopenharmony_cistatic void init_jemalloc_recycle_handler() 312570af302Sopenharmony_ci{ 313570af302Sopenharmony_ci struct sigaction action = {}; 314570af302Sopenharmony_ci action.sa_handler = NULL; 315570af302Sopenharmony_ci action.sa_sigaction = handle_recycle_cache; 316570af302Sopenharmony_ci sigemptyset(&action.sa_mask); 317570af302Sopenharmony_ci sigaddset(&action.sa_mask, MUSL_SIGNAL_RECYCLE_JEMALLOC); 318570af302Sopenharmony_ci action.sa_flags = SA_SIGINFO | SA_RESTART; 319570af302Sopenharmony_ci action.sa_restorer = NULL; 320570af302Sopenharmony_ci sigaction(MUSL_SIGNAL_RECYCLE_JEMALLOC, &action, NULL); 321570af302Sopenharmony_ci} 322570af302Sopenharmony_ci#endif 323570af302Sopenharmony_ci 324570af302Sopenharmony_cistatic bool init_hook_functions(void* shared_library_handler, struct MallocDispatchType* table, const char* prefix) 325570af302Sopenharmony_ci{ 326570af302Sopenharmony_ci if (!init_malloc_function(shared_library_handler, &table->malloc, prefix)) { 327570af302Sopenharmony_ci return false; 328570af302Sopenharmony_ci } 329570af302Sopenharmony_ci if (!init_free_function(shared_library_handler, &table->free, prefix)) { 330570af302Sopenharmony_ci return false; 331570af302Sopenharmony_ci } 332570af302Sopenharmony_ci if (!init_mmap_function(shared_library_handler, &table->mmap, prefix)) { 333570af302Sopenharmony_ci return false; 334570af302Sopenharmony_ci } 335570af302Sopenharmony_ci if (!init_munmap_function(shared_library_handler, &table->munmap, prefix)) { 336570af302Sopenharmony_ci return false; 337570af302Sopenharmony_ci } 338570af302Sopenharmony_ci if (!init_calloc_function(shared_library_handler, &table->calloc, prefix)) { 339570af302Sopenharmony_ci return false; 340570af302Sopenharmony_ci } 341570af302Sopenharmony_ci if (!init_realloc_function(shared_library_handler, &table->realloc, prefix)) { 342570af302Sopenharmony_ci return false; 343570af302Sopenharmony_ci } 344570af302Sopenharmony_ci if (!init_memtrace_function(shared_library_handler, &table->memtrace, prefix)) { 345570af302Sopenharmony_ci return false; 346570af302Sopenharmony_ci } 347570af302Sopenharmony_ci if (!init_malloc_usable_size_function(shared_library_handler, &table->malloc_usable_size, prefix)) { 348570af302Sopenharmony_ci return false; 349570af302Sopenharmony_ci } 350570af302Sopenharmony_ci if (!init_prctl_function(shared_library_handler, &table->prctl, prefix)) { 351570af302Sopenharmony_ci return false; 352570af302Sopenharmony_ci } 353570af302Sopenharmony_ci if (!init_aligned_alloc_function(shared_library_handler, &table->aligned_alloc, prefix)) { 354570af302Sopenharmony_ci return false; 355570af302Sopenharmony_ci } 356570af302Sopenharmony_ci return true; 357570af302Sopenharmony_ci} 358570af302Sopenharmony_ci 359570af302Sopenharmony_cistatic void clear_function_table() 360570af302Sopenharmony_ci{ 361570af302Sopenharmony_ci for (size_t i = 0; i < LAST_FUNCTION; i++) { 362570af302Sopenharmony_ci function_of_shared_lib[i] = NULL; 363570af302Sopenharmony_ci if (__get_memleak_hook_flag()) { 364570af302Sopenharmony_ci function_of_memleak_shared_lib[i] = NULL; 365570af302Sopenharmony_ci } else if (__get_global_hook_flag()) { 366570af302Sopenharmony_ci function_of_ohos_malloc_shared_lib[i] = NULL; 367570af302Sopenharmony_ci } 368570af302Sopenharmony_ci } 369570af302Sopenharmony_ci} 370570af302Sopenharmony_ci 371570af302Sopenharmony_cibool init_malloc_hook_shared_library(void* shared_library_handle, const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table) 372570af302Sopenharmony_ci{ 373570af302Sopenharmony_ci static const char* names[] = { 374570af302Sopenharmony_ci "initialize", 375570af302Sopenharmony_ci "finalize", 376570af302Sopenharmony_ci "get_hook_flag", 377570af302Sopenharmony_ci "set_hook_flag", 378570af302Sopenharmony_ci "on_start", 379570af302Sopenharmony_ci "on_end", 380570af302Sopenharmony_ci "send_hook_misc_data", 381570af302Sopenharmony_ci "get_hook_config", 382570af302Sopenharmony_ci }; 383570af302Sopenharmony_ci 384570af302Sopenharmony_ci for (int i = 0; i < LAST_FUNCTION; i++) { 385570af302Sopenharmony_ci char symbol[MAX_SYM_NAME_SIZE]; 386570af302Sopenharmony_ci snprintf(symbol, sizeof(symbol), "%s_%s", prefix, names[i]); 387570af302Sopenharmony_ci function_of_shared_lib[i] = dlsym(shared_library_handle, symbol); 388570af302Sopenharmony_ci if (__get_memleak_hook_flag()) { 389570af302Sopenharmony_ci function_of_memleak_shared_lib[i] = function_of_shared_lib[i]; 390570af302Sopenharmony_ci } else if (__get_global_hook_flag()) { 391570af302Sopenharmony_ci function_of_ohos_malloc_shared_lib[i] = function_of_shared_lib[i]; 392570af302Sopenharmony_ci } 393570af302Sopenharmony_ci if (function_of_shared_lib[i] == NULL) { 394570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "%s: %s routine not found in %s\n", getprogname(), symbol, shared_lib); 395570af302Sopenharmony_ci clear_function_table(); 396570af302Sopenharmony_ci return false; 397570af302Sopenharmony_ci } 398570af302Sopenharmony_ci } 399570af302Sopenharmony_ci 400570af302Sopenharmony_ci if (!init_hook_functions(shared_library_handle, dispatch_table, prefix)) { 401570af302Sopenharmony_ci clear_function_table(); 402570af302Sopenharmony_ci return false; 403570af302Sopenharmony_ci } 404570af302Sopenharmony_ci 405570af302Sopenharmony_ci return true; 406570af302Sopenharmony_ci} 407570af302Sopenharmony_ci 408570af302Sopenharmony_civoid* load_malloc_hook_shared_library(const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table) 409570af302Sopenharmony_ci{ 410570af302Sopenharmony_ci void* shared_library_handle = NULL; 411570af302Sopenharmony_ci 412570af302Sopenharmony_ci shared_library_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL); 413570af302Sopenharmony_ci 414570af302Sopenharmony_ci if (shared_library_handle == NULL) { 415570af302Sopenharmony_ci MUSL_LOGI("HiProfiler, Unable to open shared library %{public}s: %{public}s.", shared_lib, dlerror()); 416570af302Sopenharmony_ci return NULL; 417570af302Sopenharmony_ci } 418570af302Sopenharmony_ci 419570af302Sopenharmony_ci if (!init_malloc_hook_shared_library(shared_library_handle, shared_lib, prefix, dispatch_table)) { 420570af302Sopenharmony_ci dlclose(shared_library_handle); 421570af302Sopenharmony_ci shared_library_handle = NULL; 422570af302Sopenharmony_ci } 423570af302Sopenharmony_ci MUSL_LOGI("HiProfiler, load_malloc_hook_shared_library success."); 424570af302Sopenharmony_ci return shared_library_handle; 425570af302Sopenharmony_ci} 426570af302Sopenharmony_ci 427570af302Sopenharmony_citypedef void (*finalize_func_t)(); 428570af302Sopenharmony_citypedef bool (*init_func_t)(const struct MallocDispatchType*, bool*, const char*); 429570af302Sopenharmony_citypedef bool (*on_start_func_t)(); 430570af302Sopenharmony_citypedef bool (*on_end_func_t)(); 431570af302Sopenharmony_ci 432570af302Sopenharmony_cistatic void malloc_finalize() 433570af302Sopenharmony_ci{ 434570af302Sopenharmony_ci __set_hook_flag(false); 435570af302Sopenharmony_ci ((finalize_func_t)function_of_shared_lib[FINALIZE_FUNCTION])(); 436570af302Sopenharmony_ci 437570af302Sopenharmony_ci fclose(stdin); 438570af302Sopenharmony_ci fclose(stdout); 439570af302Sopenharmony_ci fclose(stderr); 440570af302Sopenharmony_ci} 441570af302Sopenharmony_ci 442570af302Sopenharmony_cibool finish_install_ohos_malloc_hooks(struct musl_libc_globals* globals, const char* options, const char* prefix, void* shared_library_handle) 443570af302Sopenharmony_ci{ 444570af302Sopenharmony_ci init_func_t init_func = (init_func_t)(function_of_shared_lib[INITIALIZE_FUNCTION]); 445570af302Sopenharmony_ci if (!init_func(&__libc_malloc_default_dispatch, NULL, options)) { 446570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc %s\n", getprogname(), prefix); 447570af302Sopenharmony_ci clear_function_table(); 448570af302Sopenharmony_ci return false; 449570af302Sopenharmony_ci } 450570af302Sopenharmony_ci on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]); 451570af302Sopenharmony_ci if (__get_global_hook_flag()) { 452570af302Sopenharmony_ci if (!start_func(__uninstal_malloc_hook)) { 453570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "%s: failed to start %s\n", getprogname(), prefix); 454570af302Sopenharmony_ci clear_function_table(); 455570af302Sopenharmony_ci return false; 456570af302Sopenharmony_ci } 457570af302Sopenharmony_ci atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)shared_library_handle, memory_order_seq_cst); 458570af302Sopenharmony_ci atomic_store_explicit(&__musl_libc_globals.so_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst); 459570af302Sopenharmony_ci atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst); 460570af302Sopenharmony_ci } 461570af302Sopenharmony_ci if (__get_memleak_hook_flag() && checkLoadMallocMemTrack) { 462570af302Sopenharmony_ci if (!start_func(memLeakTypeContent)) { 463570af302Sopenharmony_ci clear_function_table(); 464570af302Sopenharmony_ci return false; 465570af302Sopenharmony_ci } 466570af302Sopenharmony_ci atomic_store_explicit(&__musl_libc_globals.memleak_tracker_so_dispatch_table, (volatile long long)&globals->memleak_tracker_malloc_dispatch_table, memory_order_seq_cst); 467570af302Sopenharmony_ci atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)&globals->memleak_tracker_malloc_dispatch_table, memory_order_seq_cst); 468570af302Sopenharmony_ci } 469570af302Sopenharmony_ci int ret_value = atexit(malloc_finalize); 470570af302Sopenharmony_ci if (ret_value != 0) { 471570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "failed to set atexit cleanup function: %d\n", ret_value); 472570af302Sopenharmony_ci } 473570af302Sopenharmony_ci return true; 474570af302Sopenharmony_ci} 475570af302Sopenharmony_ci 476570af302Sopenharmony_cistatic bool is_empty_string(const char* str) 477570af302Sopenharmony_ci{ 478570af302Sopenharmony_ci while (*str) { 479570af302Sopenharmony_ci if (!isspace((unsigned char)(*str))) { 480570af302Sopenharmony_ci return false; 481570af302Sopenharmony_ci } 482570af302Sopenharmony_ci } 483570af302Sopenharmony_ci return true; 484570af302Sopenharmony_ci} 485570af302Sopenharmony_ci 486570af302Sopenharmony_cistatic void install_ohos_malloc_hook(struct musl_libc_globals* globals, const char* shared_lib, const char* prefix) 487570af302Sopenharmony_ci{ 488570af302Sopenharmony_ci volatile void* shared_library_handle = (volatile void *)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire); 489570af302Sopenharmony_ci assert(shared_library_handle == NULL || shared_library_handle == (volatile void*)-1); 490570af302Sopenharmony_ci if (__get_memleak_hook_flag()) { 491570af302Sopenharmony_ci shared_library_handle = (volatile void*)load_malloc_hook_shared_library(shared_lib, prefix, &globals->memleak_tracker_malloc_dispatch_table); 492570af302Sopenharmony_ci } else if (__get_global_hook_flag()) { 493570af302Sopenharmony_ci shared_library_handle = (volatile void*)load_malloc_hook_shared_library(shared_lib, prefix, &globals->malloc_dispatch_table); 494570af302Sopenharmony_ci } 495570af302Sopenharmony_ci if (shared_library_handle == NULL) { 496570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "Can't load shared library '%s'\n", __malloc_hook_shared_lib); 497570af302Sopenharmony_ci return; 498570af302Sopenharmony_ci } 499570af302Sopenharmony_ci 500570af302Sopenharmony_ci if (finish_install_ohos_malloc_hooks(globals, NULL, prefix, shared_library_handle)) { 501570af302Sopenharmony_ci if (strncmp(__malloc_hook_function_prefix, prefix, strlen(prefix)) == 0) { 502570af302Sopenharmony_ci atomic_store_explicit(&ohos_malloc_ever_shared_library_handle, (volatile long long)shared_library_handle, memory_order_seq_cst); 503570af302Sopenharmony_ci } else { 504570af302Sopenharmony_ci atomic_store_explicit(&memleak_ever_shared_library_handle, (volatile long long)shared_library_handle, memory_order_seq_cst); 505570af302Sopenharmony_ci } 506570af302Sopenharmony_ci } else { 507570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "finish_install_ohos_malloc_hooks failed\n"); 508570af302Sopenharmony_ci dlclose((void *)shared_library_handle); 509570af302Sopenharmony_ci atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)0, memory_order_seq_cst); 510570af302Sopenharmony_ci } 511570af302Sopenharmony_ci} 512570af302Sopenharmony_ci 513570af302Sopenharmony_cistatic void* init_ohos_malloc_hook() 514570af302Sopenharmony_ci{ 515570af302Sopenharmony_ci if (__get_memleak_hook_flag()) { 516570af302Sopenharmony_ci get_memleak_hook_param(); 517570af302Sopenharmony_ci if (checkLoadMallocMemTrack) { 518570af302Sopenharmony_ci install_ohos_malloc_hook(&__musl_libc_globals, kMemTrackSharedLib, kMemTrackPrefix); 519570af302Sopenharmony_ci } 520570af302Sopenharmony_ci } 521570af302Sopenharmony_ci if (__get_global_hook_flag()) { 522570af302Sopenharmony_ci install_ohos_malloc_hook(&__musl_libc_globals, __malloc_hook_shared_lib, __malloc_hook_function_prefix); 523570af302Sopenharmony_ci } 524570af302Sopenharmony_ci return NULL; 525570af302Sopenharmony_ci} 526570af302Sopenharmony_ci 527570af302Sopenharmony_civoid* ohos_malloc_hook_init_function(size_t bytes) 528570af302Sopenharmony_ci{ 529570af302Sopenharmony_ci if (atomic_exchange(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL)) { 530570af302Sopenharmony_ci pthread_t thread_id; 531570af302Sopenharmony_ci MUSL_LOGI("HiProfiler, ohos_malloc_hook_init_function, pthread_create."); 532570af302Sopenharmony_ci if (pthread_create(&thread_id, NULL, init_ohos_malloc_hook, NULL) != 0) { 533570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_create\n", getprogname()); 534570af302Sopenharmony_ci } else if (pthread_detach(thread_id) != 0) { 535570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_detach\n", getprogname()); 536570af302Sopenharmony_ci } 537570af302Sopenharmony_ci } 538570af302Sopenharmony_ci void*ptr = MuslFunc(malloc)(bytes); 539570af302Sopenharmony_ci return ptr; 540570af302Sopenharmony_ci 541570af302Sopenharmony_ci} 542570af302Sopenharmony_ci 543570af302Sopenharmony_cistatic void __set_default_malloc() 544570af302Sopenharmony_ci{ 545570af302Sopenharmony_ci atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL, memory_order_seq_cst); 546570af302Sopenharmony_ci} 547570af302Sopenharmony_ci 548570af302Sopenharmony_cistatic void __restore_hook_function_table() 549570af302Sopenharmony_ci{ 550570af302Sopenharmony_ci for (size_t i = 0; i < LAST_FUNCTION; i++) { 551570af302Sopenharmony_ci if (__get_memleak_hook_flag()) { 552570af302Sopenharmony_ci function_of_shared_lib[i] = function_of_memleak_shared_lib[i]; 553570af302Sopenharmony_ci } else if (__get_global_hook_flag()) { 554570af302Sopenharmony_ci function_of_shared_lib[i] = function_of_ohos_malloc_shared_lib[i]; 555570af302Sopenharmony_ci } 556570af302Sopenharmony_ci } 557570af302Sopenharmony_ci} 558570af302Sopenharmony_ci 559570af302Sopenharmony_cistatic void __install_malloc_hook() 560570af302Sopenharmony_ci{ 561570af302Sopenharmony_ci if (__get_memleak_hook_flag()) { 562570af302Sopenharmony_ci return; 563570af302Sopenharmony_ci } 564570af302Sopenharmony_ci atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst); 565570af302Sopenharmony_ci volatile void* ohos_malloc_ever_handle = (volatile void*)atomic_load_explicit(&ohos_malloc_ever_shared_library_handle, memory_order_acquire); 566570af302Sopenharmony_ci if (ohos_malloc_ever_handle != NULL) { 567570af302Sopenharmony_ci atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)ohos_malloc_ever_handle, memory_order_seq_cst); 568570af302Sopenharmony_ci } else { 569570af302Sopenharmony_ci atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)0, memory_order_seq_cst); 570570af302Sopenharmony_ci } 571570af302Sopenharmony_ci volatile void* shared_library_handle = (volatile void*)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire); 572570af302Sopenharmony_ci if (shared_library_handle == NULL) { 573570af302Sopenharmony_ci MUSL_LOGI("HiProfiler, __install_malloc_hook __hook_mode %{public}d", __hook_mode); 574570af302Sopenharmony_ci if (__hook_mode == STEP_HOOK_MODE) { 575570af302Sopenharmony_ci atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)&__ohos_malloc_hook_init_dispatch, memory_order_seq_cst); 576570af302Sopenharmony_ci atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)-1, memory_order_seq_cst); 577570af302Sopenharmony_ci } else { 578570af302Sopenharmony_ci init_ohos_malloc_hook(); 579570af302Sopenharmony_ci } 580570af302Sopenharmony_ci } else if (shared_library_handle != (void*)-1) { 581570af302Sopenharmony_ci __restore_hook_function_table(); 582570af302Sopenharmony_ci on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]); 583570af302Sopenharmony_ci if (start_func && !start_func(__uninstal_malloc_hook)) { 584570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc\n", getprogname()); 585570af302Sopenharmony_ci } 586570af302Sopenharmony_ci volatile const struct MallocDispatchType* so_dispatch_value = (volatile const struct MallocDispatchType*)atomic_load_explicit(&__musl_libc_globals.so_dispatch_table, memory_order_acquire); 587570af302Sopenharmony_ci atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)so_dispatch_value, memory_order_seq_cst); 588570af302Sopenharmony_ci } 589570af302Sopenharmony_ci} 590570af302Sopenharmony_ci 591570af302Sopenharmony_cistatic void __uninstal_malloc_hook() 592570af302Sopenharmony_ci{ 593570af302Sopenharmony_ci if (__get_memleak_hook_flag()) { 594570af302Sopenharmony_ci return; 595570af302Sopenharmony_ci } 596570af302Sopenharmony_ci if (!atomic_load_explicit(&__hook_enable_hook_flag, memory_order_acquire)) { 597570af302Sopenharmony_ci return; 598570af302Sopenharmony_ci } 599570af302Sopenharmony_ci bool expected = true; 600570af302Sopenharmony_ci if (atomic_compare_exchange_strong_explicit(&__hook_enable_hook_flag, &expected, false, memory_order_release, memory_order_relaxed)) { 601570af302Sopenharmony_ci bool flag = __set_hook_flag(false); 602570af302Sopenharmony_ci __set_default_malloc(); 603570af302Sopenharmony_ci on_end_func_t end_func = (on_end_func_t)(function_of_shared_lib[ON_END_FUNCTION]); 604570af302Sopenharmony_ci if (end_func) { 605570af302Sopenharmony_ci end_func(); 606570af302Sopenharmony_ci } 607570af302Sopenharmony_ci } 608570af302Sopenharmony_ci} 609570af302Sopenharmony_ci 610570af302Sopenharmony_cistatic void __install_memleak_tracker_hook(int32_t sigNum, siginfo_t *info, void *ptr) 611570af302Sopenharmony_ci{ 612570af302Sopenharmony_ci if (__get_global_hook_flag()) { 613570af302Sopenharmony_ci return; 614570af302Sopenharmony_ci } 615570af302Sopenharmony_ci atomic_store_explicit(&__memleak_hook_flag, (volatile bool)true, memory_order_seq_cst); 616570af302Sopenharmony_ci volatile void* memleak_ever_handle = (volatile void*)atomic_load_explicit(&memleak_ever_shared_library_handle, memory_order_acquire); 617570af302Sopenharmony_ci if (memleak_ever_handle != NULL) { 618570af302Sopenharmony_ci atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)memleak_ever_handle, memory_order_seq_cst); 619570af302Sopenharmony_ci } else { 620570af302Sopenharmony_ci atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)0, memory_order_seq_cst); 621570af302Sopenharmony_ci } 622570af302Sopenharmony_ci volatile void* shared_library_handle = (volatile void*)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire); 623570af302Sopenharmony_ci memLeakTypeContent = (unsigned int)(siginfo_t *)((info)->si_addr); 624570af302Sopenharmony_ci if (shared_library_handle == NULL) { 625570af302Sopenharmony_ci if (__hook_mode == STEP_HOOK_MODE) { 626570af302Sopenharmony_ci if (memLeakTypeContent & ADDR_NATIVE_ENABLE) { 627570af302Sopenharmony_ci atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)&__ohos_malloc_hook_init_dispatch, memory_order_seq_cst); 628570af302Sopenharmony_ci atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)-1, memory_order_seq_cst); 629570af302Sopenharmony_ci } 630570af302Sopenharmony_ci } else { 631570af302Sopenharmony_ci init_ohos_malloc_hook(); 632570af302Sopenharmony_ci } 633570af302Sopenharmony_ci } else if (shared_library_handle != (void*)-1) { 634570af302Sopenharmony_ci if (checkLoadMallocMemTrack) { 635570af302Sopenharmony_ci __restore_hook_function_table(); 636570af302Sopenharmony_ci on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]); 637570af302Sopenharmony_ci if (memLeakTypeContent & ADDR_NATIVE_ENABLE) { 638570af302Sopenharmony_ci volatile const struct MallocDispatchType* memleak_tracker_so_dispatch_value = (volatile const struct MallocDispatchType*)atomic_load_explicit(&__musl_libc_globals.memleak_tracker_so_dispatch_table, memory_order_acquire); 639570af302Sopenharmony_ci atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)memleak_tracker_so_dispatch_value, memory_order_seq_cst); 640570af302Sopenharmony_ci } 641570af302Sopenharmony_ci if (start_func && !start_func(memLeakTypeContent)) { 642570af302Sopenharmony_ci // __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc\n", getprogname()); 643570af302Sopenharmony_ci clear_function_table(); 644570af302Sopenharmony_ci } 645570af302Sopenharmony_ci if (memLeakTypeContent & ADDR_NATIVE_CLEAR) { 646570af302Sopenharmony_ci atomic_store_explicit(&__memleak_hook_flag, (volatile bool)false, memory_order_seq_cst); 647570af302Sopenharmony_ci bool flag = __set_hook_flag(false); 648570af302Sopenharmony_ci __set_default_malloc(); 649570af302Sopenharmony_ci on_end_func_t end_func = (on_end_func_t)(function_of_shared_lib[ON_END_FUNCTION]); 650570af302Sopenharmony_ci if (end_func) { 651570af302Sopenharmony_ci end_func(); 652570af302Sopenharmony_ci } 653570af302Sopenharmony_ci memLeakTypeContent = 0; 654570af302Sopenharmony_ci } 655570af302Sopenharmony_ci } 656570af302Sopenharmony_ci } 657570af302Sopenharmony_ci} 658570af302Sopenharmony_ci 659570af302Sopenharmony_ci 660570af302Sopenharmony_cistatic void __install_malloc_hook_signal_handler() 661570af302Sopenharmony_ci{ 662570af302Sopenharmony_ci struct sigaction actionInstallHook = {}; 663570af302Sopenharmony_ci actionInstallHook.sa_handler = __install_malloc_hook; 664570af302Sopenharmony_ci sigemptyset(&actionInstallHook.sa_mask); 665570af302Sopenharmony_ci sigaddset(&actionInstallHook.sa_mask, MUSL_SIGNAL_UNHOOK); 666570af302Sopenharmony_ci sigaction(MUSL_SIGNAL_HOOK, &actionInstallHook, NULL); 667570af302Sopenharmony_ci 668570af302Sopenharmony_ci struct sigaction actionDef = {}; 669570af302Sopenharmony_ci actionDef.sa_handler = __uninstal_malloc_hook; 670570af302Sopenharmony_ci sigemptyset(&actionDef.sa_mask); 671570af302Sopenharmony_ci sigaddset(&actionDef.sa_mask, MUSL_SIGNAL_HOOK); 672570af302Sopenharmony_ci sigaction(MUSL_SIGNAL_UNHOOK, &actionDef, NULL); 673570af302Sopenharmony_ci 674570af302Sopenharmony_ci struct sigaction actionInstallMemleakHook = {}; 675570af302Sopenharmony_ci actionInstallMemleakHook.sa_handler = NULL; 676570af302Sopenharmony_ci actionInstallMemleakHook.sa_sigaction = __install_memleak_tracker_hook; 677570af302Sopenharmony_ci sigemptyset(&actionInstallMemleakHook.sa_mask); 678570af302Sopenharmony_ci sigaddset(&actionInstallMemleakHook.sa_mask, MUSL_SIGNAL_MEMCHECK); 679570af302Sopenharmony_ci actionInstallMemleakHook.sa_flags = SA_SIGINFO; 680570af302Sopenharmony_ci actionInstallMemleakHook.sa_restorer = NULL; 681570af302Sopenharmony_ci sigaction(MUSL_SIGNAL_MEMCHECK, &actionInstallMemleakHook, NULL); 682570af302Sopenharmony_ci} 683570af302Sopenharmony_ci 684570af302Sopenharmony_cistatic void __initialize_malloc() 685570af302Sopenharmony_ci{ 686570af302Sopenharmony_ci __install_malloc_hook_signal_handler(); 687570af302Sopenharmony_ci#ifdef USE_JEMALLOC_RECYCLE_FUNC 688570af302Sopenharmony_ci init_jemalloc_recycle_handler(); 689570af302Sopenharmony_ci#endif 690570af302Sopenharmony_ci} 691570af302Sopenharmony_ci 692570af302Sopenharmony_ci__attribute__((constructor(1))) static void __musl_initialize() 693570af302Sopenharmony_ci{ 694570af302Sopenharmony_ci atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst); 695570af302Sopenharmony_ci atomic_store_explicit(&__memleak_hook_flag, (volatile bool)false, memory_order_seq_cst); 696570af302Sopenharmony_ci __set_default_malloc(); 697570af302Sopenharmony_ci char hook_process_path[MAX_PROC_NAME_SIZE + 1] = {0}; 698570af302Sopenharmony_ci parse_hook_variable(&__hook_mode, hook_process_path, sizeof(hook_process_path) - 1); 699570af302Sopenharmony_ci MUSL_LOGI("HiProfiler, __musl_initialize %{public}d", __hook_mode); 700570af302Sopenharmony_ci if (__hook_mode == STARTUP_HOOK_MODE) { 701570af302Sopenharmony_ci char proc_name[MAX_PROC_NAME_SIZE + 1] = {0}; 702570af302Sopenharmony_ci if (get_proc_name(getpid(), proc_name, sizeof(proc_name) - 1)) { 703570af302Sopenharmony_ci const char *pos = strrchr(proc_name, '/'); 704570af302Sopenharmony_ci const char* file_name; 705570af302Sopenharmony_ci if (pos != NULL) { 706570af302Sopenharmony_ci file_name = pos + 1; 707570af302Sopenharmony_ci } else { 708570af302Sopenharmony_ci file_name = proc_name; 709570af302Sopenharmony_ci } 710570af302Sopenharmony_ci MUSL_LOGI("HiProfiler, current proc %{public}s, , target proc %{public}s", file_name, hook_process_path); 711570af302Sopenharmony_ci if (strncmp(file_name, hook_process_path, strlen(hook_process_path)) == 0) { 712570af302Sopenharmony_ci atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst); 713570af302Sopenharmony_ci init_ohos_malloc_hook(); 714570af302Sopenharmony_ci } else { 715570af302Sopenharmony_ci __hook_mode = STEP_HOOK_MODE; 716570af302Sopenharmony_ci } 717570af302Sopenharmony_ci } else { 718570af302Sopenharmony_ci __hook_mode = STEP_HOOK_MODE; 719570af302Sopenharmony_ci } 720570af302Sopenharmony_ci } 721570af302Sopenharmony_ci __initialize_malloc(); 722570af302Sopenharmony_ci errno = 0; 723570af302Sopenharmony_ci} 724570af302Sopenharmony_ci#endif 725