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