1 /*
2 The hook mode has 3 kinds which can be set by command "param set":
3 (1) param set libc.hook_mode "startup:\"prog1 \""
4 (2) param set libc.hook_mode startup:program1
5 (3) param set libc.hook_mode step
6 (4) param set libc.hook_mode direct
7
8 Case 1 represents "startup" mode, and the hooked process is "prog1 ",
9 which loads hooking shared library when the program starts up.
10 The path is added with two quotation marks because a quotation mark is a special charcter,
11 which need be escaped.
12 (2) is similar with (1), but no escaped character, so quotation marks doesn't need.
13 (3) represents "step" mode, which loads hooking shared library by some steps.
14 (4) represetnt "direct" mode, which loads hooking shared library by a step.
15 */
16
17 #ifdef HOOK_ENABLE
18 #include <unistd.h>
19 #include <signal.h>
20 #include "musl_malloc_dispatch_table.h"
21 #include "musl_malloc.h"
22 #include "memory_tag.h"
23 #include "musl_preinit_common.h"
24 #ifdef OHOS_ENABLE_PARAMETER
25 #include "sys_param.h"
26 #endif
27 #include <pthread.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <dlfcn.h>
31 #include <errno.h>
32 #include <stdatomic.h>
33 #include <ctype.h>
34 #include <assert.h>
35 #include <string.h>
36 #include <malloc.h>
37
38 void* ohos_malloc_hook_init_function(size_t bytes);
39
40 static struct MallocDispatchType __ohos_malloc_hook_init_dispatch = {
41 .malloc = ohos_malloc_hook_init_function,
42 .free = MuslMalloc(free),
43 .mmap = MuslMalloc(mmap),
44 .munmap = MuslMalloc(munmap),
45 .calloc = MuslMalloc(calloc),
46 .realloc = MuslMalloc(realloc),
47 };
48 #define MAX_SYM_NAME_SIZE 1000
49 #define MAX_PROC_NAME_SIZE 256
50 #define ADDR_NATIVE_ENABLE (1<<4)
51 #define ADDR_NATIVE_DISABLE (1<<5)
52 #define ADDR_NATIVE_SAVE (1<<6)
53 #define ADDR_NATIVE_CLEAR (1<<7)
54 static char *__malloc_hook_shared_lib = "libnative_hook.z.so";
55 static char *__malloc_hook_function_prefix = "ohos_malloc_hook";
56 volatile atomic_llong ohos_malloc_hook_shared_library;
57 static char *kMemTrackSharedLib = "libmemleak_tracker.so";
58 static char *kMemTrackPrefix = "track";
59 static char *kMemTrackPropertyEnable = "const.hiview.memleak_tracker.enable";
60 static char *kMemTrackSign = "true";
61 bool checkLoadMallocMemTrack = false;
62 unsigned int memLeakTypeContent = 0;
63 volatile atomic_llong memleak_ever_shared_library_handle;
64 volatile atomic_llong ohos_malloc_ever_shared_library_handle;
65 void* function_of_shared_lib[LAST_FUNCTION];
66 void* function_of_ohos_malloc_shared_lib[LAST_FUNCTION];
67 void* function_of_memleak_shared_lib[LAST_FUNCTION];
68 static enum EnumHookMode __hook_mode = STEP_HOOK_MODE;
69
get_native_hook_param(char * buf,unsigned int buf_len)70 static void get_native_hook_param(char *buf, unsigned int buf_len)
71 {
72 #ifdef OHOS_ENABLE_PARAMETER
73 const char *key = MUSL_HOOK_PARAM_NAME;
74 unsigned int len = buf_len;
75 (void)SystemReadParam(key, buf, &len);
76 #else
77 return;
78 #endif
79 }
80
get_memleak_hook_param()81 static void get_memleak_hook_param()
82 {
83 #ifdef OHOS_ENABLE_PARAMETER
84 const char *key = kMemTrackPropertyEnable;
85 unsigned int len = OHOS_PARAM_MAX_SIZE;
86 char memleak_param_value[OHOS_PARAM_MAX_SIZE + 1] = {0};
87 (void)SystemReadParam(key, memleak_param_value, &len);
88 if (strncmp(memleak_param_value, kMemTrackSign, strlen(kMemTrackSign)) == 0) {
89 checkLoadMallocMemTrack = true;
90 }
91 #else
92 return;
93 #endif
94 }
95
parse_hook_variable(enum EnumHookMode * mode,char * path,int size)96 static int parse_hook_variable(enum EnumHookMode* mode, char* path, int size)
97 {
98 if (!mode || !path || size <= 0) {
99 return -1;
100 }
101 char hook_param_value[OHOS_PARAM_MAX_SIZE + 1] = {0};
102 unsigned int len = OHOS_PARAM_MAX_SIZE;
103 get_native_hook_param(hook_param_value, len);
104 if (hook_param_value[0] == '\0') {
105 *mode = STEP_HOOK_MODE;
106 path[0] = '\0';
107 } else {
108 char* ptr = hook_param_value;
109 while (*ptr && *ptr != ':') {
110 ++ptr;
111 }
112
113 if (*ptr == ':') {
114 *ptr = '\0';
115 ++ptr;
116 }
117
118 if (strcmp(hook_param_value, "startup") == 0) {
119 *mode = STARTUP_HOOK_MODE;
120 } else if (strcmp(hook_param_value, "direct") == 0) {
121 *mode = DIRECT_HOOK_MODE;
122 } else if (strcmp(hook_param_value, "step") == 0) {
123 *mode = STEP_HOOK_MODE;
124 } else {
125 *mode = STEP_HOOK_MODE;
126 }
127 if (*mode == STARTUP_HOOK_MODE) {
128 if (*ptr == '\"') {
129 ++ptr;
130 int idx = 0;
131 while (idx < size - 1 && *ptr && *ptr != '\"') {
132 path[idx++] = *ptr++;
133 }
134 path[idx] = '\0';
135 } else {
136 int idx = 0;
137 while (idx < size - 1 && *ptr) {
138 path[idx++] = *ptr++;
139 }
140 path[idx] = '\0';
141 }
142 }
143 }
144 return 0;
145 }
146
get_proc_name(pid_t pid,char * buf,unsigned int buf_len)147 static bool get_proc_name(pid_t pid, char *buf, unsigned int buf_len)
148 {
149 if (pid <= 0) {
150 return false;
151 }
152 char target_file[FILE_NAME_MAX_SIZE] = {0};
153 (void)snprintf(target_file, sizeof(target_file), "/proc/%d/cmdline", pid);
154 FILE *f = fopen(target_file, "r");
155 if (f == NULL) {
156 return false;
157 }
158 if (fgets(buf, buf_len, f) == NULL) {
159 (void)fclose(f);
160 return false;
161 }
162 (void)fclose(f);
163 return true;
164 }
165
init_malloc_function(void * malloc_shared_library_handler,MallocMallocType * func,const char * prefix)166 static bool init_malloc_function(void* malloc_shared_library_handler, MallocMallocType* func, const char* prefix)
167 {
168 char symbol[MAX_SYM_NAME_SIZE];
169 snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "malloc");
170 *func = (MallocMallocType)(dlsym(malloc_shared_library_handler, symbol));
171 if (*func == NULL) {
172 return false;
173 }
174 return true;
175 }
176
init_free_function(void * malloc_shared_library_handler,MallocFreeType * func,const char * prefix)177 static bool init_free_function(void* malloc_shared_library_handler, MallocFreeType* func, const char* prefix)
178 {
179 char symbol[MAX_SYM_NAME_SIZE];
180 snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "free");
181 *func = (MallocFreeType)(dlsym(malloc_shared_library_handler, symbol));
182 if (*func == NULL) {
183 return false;
184 }
185 return true;
186 }
187
init_mmap_function(void * malloc_shared_library_handler,MallocMmapType * func,const char * prefix)188 static bool init_mmap_function(void* malloc_shared_library_handler, MallocMmapType* func, const char* prefix)
189 {
190 char symbol[MAX_SYM_NAME_SIZE];
191 snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "mmap");
192 *func = (MallocMmapType)(dlsym(malloc_shared_library_handler, symbol));
193 if (*func == NULL) {
194 return false;
195 }
196 return true;
197 }
198
init_munmap_function(void * malloc_shared_library_handler,MallocMunmapType * func,const char * prefix)199 static bool init_munmap_function(void* malloc_shared_library_handler, MallocMunmapType* func, const char* prefix)
200 {
201 char symbol[MAX_SYM_NAME_SIZE];
202 snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "munmap");
203 *func = (MallocMunmapType)(dlsym(malloc_shared_library_handler, symbol));
204 if (*func == NULL) {
205 return false;
206 }
207 return true;
208 }
209
init_memorytag_function(void * malloc_shared_library_handler,const char * prefix)210 static bool init_memorytag_function(void* malloc_shared_library_handler, const char* prefix)
211 {
212 char symbol[MAX_SYM_NAME_SIZE];
213 snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "memtag");
214 __mem_typeset = (mtypeset)(dlsym(malloc_shared_library_handler, symbol));
215
216 if (__mem_typeset == NULL) {
217 return false;
218 }
219 return true;
220 }
221
init_calloc_function(void * malloc_shared_library_handler,MallocCallocType * func,const char * prefix)222 static bool init_calloc_function(void* malloc_shared_library_handler, MallocCallocType* func, const char* prefix)
223 {
224 char symbol[MAX_SYM_NAME_SIZE];
225 snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "calloc");
226 *func = (MallocCallocType)(dlsym(malloc_shared_library_handler, symbol));
227 if (*func == NULL) {
228 return false;
229 }
230 return true;
231 }
232
init_realloc_function(void * malloc_shared_library_handler,MallocReallocType * func,const char * prefix)233 static bool init_realloc_function(void* malloc_shared_library_handler, MallocReallocType* func, const char* prefix)
234 {
235 char symbol[MAX_SYM_NAME_SIZE];
236 snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "realloc");
237 *func = (MallocReallocType)(dlsym(malloc_shared_library_handler, symbol));
238 if (*func == NULL) {
239 return false;
240 }
241 return true;
242 }
243
init_malloc_usable_size_function(void * malloc_shared_library_handler,MallocMallocUsableSizeType * func,const char * prefix)244 static bool init_malloc_usable_size_function(void* malloc_shared_library_handler, MallocMallocUsableSizeType* func, const char* prefix)
245 {
246 char symbol[MAX_SYM_NAME_SIZE];
247 snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "malloc_usable_size");
248 *func = (MallocMallocUsableSizeType)(dlsym(malloc_shared_library_handler, symbol));
249 if (*func == NULL) {
250 return false;
251 }
252 return true;
253 }
254
init_hook_functions(void * shared_library_handler,struct MallocDispatchType * table,const char * prefix)255 static bool init_hook_functions(void* shared_library_handler, struct MallocDispatchType* table, const char* prefix)
256 {
257 if (!init_malloc_function(shared_library_handler, &table->malloc, prefix)) {
258 return false;
259 }
260 if (!init_free_function(shared_library_handler, &table->free, prefix)) {
261 return false;
262 }
263 if (!init_mmap_function(shared_library_handler, &table->mmap, prefix)) {
264 return false;
265 }
266 if (!init_munmap_function(shared_library_handler, &table->munmap, prefix)) {
267 return false;
268 }
269 if (!init_calloc_function(shared_library_handler, &table->calloc, prefix)) {
270 return false;
271 }
272 if (!init_realloc_function(shared_library_handler, &table->realloc, prefix)) {
273 return false;
274 }
275 if (!init_memorytag_function(shared_library_handler, prefix)) {
276 return false;
277 }
278 if (!init_malloc_usable_size_function(shared_library_handler, &table->malloc_usable_size, prefix)) {
279 return false;
280 }
281 return true;
282 }
283
clear_function_table()284 static void clear_function_table()
285 {
286 for (size_t i = 0; i < LAST_FUNCTION; i++) {
287 function_of_shared_lib[i] = NULL;
288 if (__get_memleak_hook_flag()) {
289 function_of_memleak_shared_lib[i] = NULL;
290 } else if (__get_global_hook_flag()) {
291 function_of_ohos_malloc_shared_lib[i] = NULL;
292 }
293 }
294 }
295
init_malloc_hook_shared_library(void * shared_library_handle,const char * shared_lib,const char * prefix,struct MallocDispatchType * dispatch_table)296 bool init_malloc_hook_shared_library(void* shared_library_handle, const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table)
297 {
298 static const char* names[] = {
299 "initialize",
300 "finalize",
301 "get_hook_flag",
302 "set_hook_flag",
303 "on_start",
304 "on_end",
305 };
306
307 for (int i = 0; i < LAST_FUNCTION; i++) {
308 char symbol[MAX_SYM_NAME_SIZE];
309 snprintf(symbol, sizeof(symbol), "%s_%s", prefix, names[i]);
310 function_of_shared_lib[i] = dlsym(shared_library_handle, symbol);
311 if (__get_memleak_hook_flag()) {
312 function_of_memleak_shared_lib[i] = function_of_shared_lib[i];
313 } else if (__get_global_hook_flag()) {
314 function_of_ohos_malloc_shared_lib[i] = function_of_shared_lib[i];
315 }
316 if (function_of_shared_lib[i] == NULL) {
317 // __musl_log(__MUSL_LOG_ERROR, "%s: %s routine not found in %s\n", getprogname(), symbol, shared_lib);
318 clear_function_table();
319 return false;
320 }
321 }
322
323 if (!init_hook_functions(shared_library_handle, dispatch_table, prefix)) {
324 clear_function_table();
325 return false;
326 }
327
328 return true;
329 }
330
load_malloc_hook_shared_library(const char * shared_lib,const char * prefix,struct MallocDispatchType * dispatch_table)331 void* load_malloc_hook_shared_library(const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table)
332 {
333 void* shared_library_handle = NULL;
334
335 shared_library_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL);
336
337 if (shared_library_handle == NULL) {
338 printf("Unable to open shared library %s: %s\n", shared_lib, dlerror());
339 return NULL;
340 }
341
342 if (!init_malloc_hook_shared_library(shared_library_handle, shared_lib, prefix, dispatch_table)) {
343 dlclose(shared_library_handle);
344 shared_library_handle = NULL;
345 }
346 // printf("load_malloc_hook_shared_library success new version test\n");
347 return shared_library_handle;
348 }
349
350 typedef void (*finalize_func_t)();
351 typedef bool (*init_func_t)(const struct MallocDispatchType*, bool*, const char*);
352 typedef bool (*on_start_func_t)();
353 typedef bool (*on_end_func_t)();
354
malloc_finalize()355 static void malloc_finalize()
356 {
357 __set_hook_flag(false);
358 ((finalize_func_t)function_of_shared_lib[FINALIZE_FUNCTION])();
359
360 fclose(stdin);
361 fclose(stdout);
362 fclose(stderr);
363 }
364
finish_install_ohos_malloc_hooks(struct musl_libc_globals * globals,const char * options,const char * prefix)365 bool finish_install_ohos_malloc_hooks(struct musl_libc_globals* globals, const char* options, const char* prefix)
366 {
367 init_func_t init_func = (init_func_t)(function_of_shared_lib[INITIALIZE_FUNCTION]);
368 if (!init_func(&__libc_malloc_default_dispatch, NULL, options)) {
369 // __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc %s\n", getprogname(), prefix);
370 clear_function_table();
371 return false;
372 }
373 on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
374 if (__get_global_hook_flag()) {
375 if (!start_func()) {
376 // __musl_log(__MUSL_LOG_ERROR, "%s: failed to start %s\n", getprogname(), prefix);
377 clear_function_table();
378 return false;
379 }
380 atomic_store_explicit(&__musl_libc_globals.so_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst);
381 atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst);
382 }
383 if (__get_memleak_hook_flag() && checkLoadMallocMemTrack) {
384 if (!start_func(memLeakTypeContent)) {
385 clear_function_table();
386 return false;
387 }
388 atomic_store_explicit(&__musl_libc_globals.memleak_tracker_so_dispatch_table, (volatile long long)&globals->memleak_tracker_malloc_dispatch_table, memory_order_seq_cst);
389 atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)&globals->memleak_tracker_malloc_dispatch_table, memory_order_seq_cst);
390 }
391 int ret_value = atexit(malloc_finalize);
392 if (ret_value != 0) {
393 // __musl_log(__MUSL_LOG_ERROR, "failed to set atexit cleanup function: %d\n", ret_value);
394 }
395 return true;
396 }
397
is_empty_string(const char * str)398 static bool is_empty_string(const char* str)
399 {
400 while (*str) {
401 if (!isspace((unsigned char)(*str))) {
402 return false;
403 }
404 }
405 return true;
406 }
407
install_ohos_malloc_hook(struct musl_libc_globals * globals,const char * shared_lib,const char * prefix)408 static void install_ohos_malloc_hook(struct musl_libc_globals* globals, const char* shared_lib, const char* prefix)
409 {
410 volatile void* shared_library_handle = (volatile void *)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
411 assert(shared_library_handle == NULL || shared_library_handle == (volatile void*)-1);
412 if (__get_memleak_hook_flag()) {
413 shared_library_handle = (volatile void*)load_malloc_hook_shared_library(shared_lib, prefix, &globals->memleak_tracker_malloc_dispatch_table);
414 } else if (__get_global_hook_flag()) {
415 shared_library_handle = (volatile void*)load_malloc_hook_shared_library(shared_lib, prefix, &globals->malloc_dispatch_table);
416 }
417 if (shared_library_handle == NULL) {
418 // __musl_log(__MUSL_LOG_ERROR, "Can't load shared library '%s'\n", __malloc_hook_shared_lib);
419 return;
420 }
421
422 if (finish_install_ohos_malloc_hooks(globals, NULL, prefix)) {
423 atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)shared_library_handle, memory_order_seq_cst);
424 if (strncmp(__malloc_hook_function_prefix, prefix, strlen(prefix)) == 0) {
425 atomic_store_explicit(&ohos_malloc_ever_shared_library_handle, (volatile long long)shared_library_handle, memory_order_seq_cst);
426 } else {
427 atomic_store_explicit(&memleak_ever_shared_library_handle, (volatile long long)shared_library_handle, memory_order_seq_cst);
428 }
429 } else {
430 // __musl_log(__MUSL_LOG_ERROR, "finish_install_ohos_malloc_hooks failed\n");
431 dlclose((void *)shared_library_handle);
432 atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)0, memory_order_seq_cst);
433 }
434 }
435
init_ohos_malloc_hook()436 static void* init_ohos_malloc_hook()
437 {
438 if (__get_memleak_hook_flag()) {
439 get_memleak_hook_param();
440 if (checkLoadMallocMemTrack) {
441 install_ohos_malloc_hook(&__musl_libc_globals, kMemTrackSharedLib, kMemTrackPrefix);
442 }
443 }
444 if (__get_global_hook_flag()) {
445 install_ohos_malloc_hook(&__musl_libc_globals, __malloc_hook_shared_lib, __malloc_hook_function_prefix);
446 }
447 return NULL;
448 }
449
ohos_malloc_hook_init_function(size_t bytes)450 void* ohos_malloc_hook_init_function(size_t bytes)
451 {
452 if (atomic_exchange(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL)) {
453 pthread_t thread_id;
454 if (pthread_create(&thread_id, NULL, init_ohos_malloc_hook, NULL) != 0) {
455 // __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_create\n", getprogname());
456 } else if (pthread_detach(thread_id) != 0) {
457 // __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_detach\n", getprogname());
458 }
459 }
460 void*ptr = MuslMalloc(malloc)(bytes);
461 return ptr;
462
463 }
464
__set_default_malloc()465 static void __set_default_malloc()
466 {
467 atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL, memory_order_seq_cst);
468 }
469
__restore_hook_function_table()470 static void __restore_hook_function_table()
471 {
472 for (size_t i = 0; i < LAST_FUNCTION; i++) {
473 if (__get_memleak_hook_flag()) {
474 function_of_shared_lib[i] = function_of_memleak_shared_lib[i];
475 } else if (__get_global_hook_flag()) {
476 function_of_shared_lib[i] = function_of_ohos_malloc_shared_lib[i];
477 }
478 }
479 }
480
__install_malloc_hook()481 static void __install_malloc_hook()
482 {
483 if (__get_memleak_hook_flag()) {
484 return;
485 }
486 atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
487 volatile void* ohos_malloc_ever_handle = (volatile void* )atomic_load_explicit(&ohos_malloc_ever_shared_library_handle, memory_order_acquire);
488 if (ohos_malloc_ever_handle != NULL) {
489 atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)ohos_malloc_ever_handle, memory_order_seq_cst);
490 } else {
491 atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)0, memory_order_seq_cst);
492 }
493 volatile void* shared_library_handle = (volatile void* )atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
494 if (shared_library_handle == NULL) {
495 if (__hook_mode == STEP_HOOK_MODE) {
496 atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)&__ohos_malloc_hook_init_dispatch, memory_order_seq_cst);
497 atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)-1, memory_order_seq_cst);
498 } else {
499 init_ohos_malloc_hook();
500 }
501 } else if (shared_library_handle != (void*)-1) {
502 __restore_hook_function_table();
503 volatile const struct MallocDispatchType* so_dispatch_value = (volatile const struct MallocDispatchType* )atomic_load_explicit(&__musl_libc_globals.so_dispatch_table, memory_order_acquire);
504 atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)so_dispatch_value, memory_order_seq_cst);
505 on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
506 if (start_func && !start_func()) {
507 // __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc\n", getprogname());
508 }
509
510 }
511 }
512
__uninstal_malloc_hook()513 static void __uninstal_malloc_hook()
514 {
515 if (__get_memleak_hook_flag()) {
516 return;
517 }
518 atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
519 bool flag = __set_hook_flag(false);
520 __set_default_malloc();
521 on_end_func_t end_func = (on_end_func_t)(function_of_shared_lib[ON_END_FUNCTION]);
522 if (end_func) {
523 end_func();
524 }
525 }
526
__install_memleak_tracker_hook(int32_t sigNum,siginfo_t * info,void * ptr)527 static void __install_memleak_tracker_hook(int32_t sigNum, siginfo_t *info, void *ptr)
528 {
529 if (__get_global_hook_flag()) {
530 return;
531 }
532 atomic_store_explicit(&__memleak_hook_flag, (volatile bool)true, memory_order_seq_cst);
533 volatile void* memleak_ever_handle = (volatile void* )atomic_load_explicit(&memleak_ever_shared_library_handle, memory_order_acquire);
534 if (memleak_ever_handle != NULL) {
535 atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)memleak_ever_handle, memory_order_seq_cst);
536 } else {
537 atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)0, memory_order_seq_cst);
538 }
539 volatile void* shared_library_handle = (volatile void* )atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
540 memLeakTypeContent = (unsigned int)(siginfo_t *)((info)->si_addr);
541 if (shared_library_handle == NULL) {
542 if (__hook_mode == STEP_HOOK_MODE) {
543 if (memLeakTypeContent & ADDR_NATIVE_ENABLE) {
544 atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)&__ohos_malloc_hook_init_dispatch, memory_order_seq_cst);
545 atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)-1, memory_order_seq_cst);
546 }
547 } else {
548 init_ohos_malloc_hook();
549 }
550 } else if (shared_library_handle != (void*)-1) {
551 if (checkLoadMallocMemTrack) {
552 __restore_hook_function_table();
553 on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
554 if (memLeakTypeContent & ADDR_NATIVE_ENABLE) {
555 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);
556 atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)memleak_tracker_so_dispatch_value, memory_order_seq_cst);
557 }
558 if (start_func && !start_func(memLeakTypeContent)) {
559 // __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc\n", getprogname());
560 clear_function_table();
561 }
562 if (memLeakTypeContent & ADDR_NATIVE_CLEAR) {
563 atomic_store_explicit(&__memleak_hook_flag, (volatile bool)false, memory_order_seq_cst);
564 bool flag = __set_hook_flag(false);
565 __set_default_malloc();
566 on_end_func_t end_func = (on_end_func_t)(function_of_shared_lib[ON_END_FUNCTION]);
567 if (end_func) {
568 end_func();
569 }
570 memLeakTypeContent = 0;
571 }
572 }
573 }
574 }
575
576
__install_malloc_hook_signal_handler()577 static void __install_malloc_hook_signal_handler()
578 {
579 struct sigaction actionInstallHook = {};
580 actionInstallHook.sa_handler = __install_malloc_hook;
581 sigemptyset(&actionInstallHook.sa_mask);
582 sigaddset(&actionInstallHook.sa_mask, MUSL_SIGNAL_UNHOOK);
583 sigaction(MUSL_SIGNAL_HOOK, &actionInstallHook, NULL);
584
585 struct sigaction actionDef = {};
586 actionDef.sa_handler = __uninstal_malloc_hook;
587 sigemptyset(&actionDef.sa_mask);
588 sigaddset(&actionDef.sa_mask, MUSL_SIGNAL_HOOK);
589 sigaction(MUSL_SIGNAL_UNHOOK, &actionDef, NULL);
590
591 struct sigaction actionInstallMemleakHook = {};
592 actionInstallMemleakHook.sa_handler = NULL;
593 actionInstallMemleakHook.sa_sigaction = __install_memleak_tracker_hook;
594 sigemptyset(&actionInstallMemleakHook.sa_mask);
595 sigaddset(&actionInstallMemleakHook.sa_mask, MUSL_SIGNAL_MEMCHECK);
596 actionInstallMemleakHook.sa_flags = SA_SIGINFO;
597 actionInstallMemleakHook.sa_restorer = NULL;
598 sigaction(MUSL_SIGNAL_MEMCHECK, &actionInstallMemleakHook, NULL);
599 }
600
__initialize_malloc()601 static void __initialize_malloc()
602 {
603 __install_malloc_hook_signal_handler();
604 }
605
__musl_initialize()606 __attribute__((constructor(1))) static void __musl_initialize()
607 {
608 atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
609 atomic_store_explicit(&__memleak_hook_flag, (volatile bool)false, memory_order_seq_cst);
610 __set_default_malloc();
611 char hook_process_path[MAX_PROC_NAME_SIZE + 1] = {0};
612 parse_hook_variable(&__hook_mode, hook_process_path, sizeof(hook_process_path) - 1);
613 if (__hook_mode == STARTUP_HOOK_MODE) {
614 char proc_name[MAX_PROC_NAME_SIZE + 1] = {0};
615 if (get_proc_name(getpid(), proc_name, sizeof(proc_name) - 1)) {
616 const char *pos = strrchr(proc_name, '/');
617 const char* file_name;
618 if (pos != NULL) {
619 file_name = pos + 1;
620 } else {
621 file_name = proc_name;
622 }
623 if (strncmp(file_name, hook_process_path, strlen(hook_process_path)) == 0) {
624 atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
625 init_ohos_malloc_hook();
626 } else {
627 __hook_mode = STEP_HOOK_MODE;
628 }
629 } else {
630 __hook_mode = STEP_HOOK_MODE;
631 }
632 }
633 __initialize_malloc();
634 errno = 0;
635 }
636 #endif
637