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