diff --git a/porting/linux/user/src/hook/malloc_common.c b/porting/linux/user/src/hook/malloc_common.c index f4a77d2bcb5a41e94d5926e93f513a6932cdfb04..30ab7ce6bfdc64fbdd52f2fad11d658b2c3678ba 100644 --- a/porting/linux/user/src/hook/malloc_common.c +++ b/porting/linux/user/src/hook/malloc_common.c @@ -50,4 +50,14 @@ int munmap(void* addr, size_t length) return MuslMalloc(munmap)(addr, length); } } + +size_t malloc_usable_size(void* addr) +{ + volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table(); + if (__predict_false(dispatch_table != NULL)) { + return dispatch_table->malloc_usable_size(addr); + } else { + return MuslMalloc(malloc_usable_size)(addr); + } +} #endif diff --git a/porting/linux/user/src/hook/musl_preinit.c b/porting/linux/user/src/hook/musl_preinit.c index 385f353609c88a2a005eff4fdc8d922ffcebd3bb..1b67d54a48baf77ef20e2ac8ff7da3c529f3fa12 100644 --- a/porting/linux/user/src/hook/musl_preinit.c +++ b/porting/linux/user/src/hook/musl_preinit.c @@ -49,14 +49,24 @@ static struct MallocDispatchType __ohos_malloc_hook_init_dispatch = { static char *__malloc_hook_shared_lib = "libnative_hook.z.so"; static char *__malloc_hook_function_prefix = "ohos_malloc_hook"; volatile atomic_llong ohos_malloc_hook_shared_library; +static char *kMemTrackSharedLib = "libmemleak_tracker.so"; +static char *kMemTrackPrefix = "track"; +static char *kMemTrackPropertyEnable = "const.hiview.memleak_tracker.enable"; +static char *kMemTrackSign = "true"; +bool checkLoadMallocMemTrack = false; void* function_of_shared_lib[LAST_FUNCTION]; static enum EnumHookMode __hook_mode = STEP_HOOK_MODE; +static char __memleak_param_value[OHOS_PARAM_MAX_SIZE + 1] = {0}; static void get_native_hook_param(char *buf, unsigned int buf_len) { #ifdef OHOS_ENABLE_PARAMETER const char *key = MUSL_HOOK_PARAM_NAME; unsigned int len = buf_len; + (void)SystemReadParam(kMemTrackPropertyEnable, __memleak_param_value, &len); + if (strncmp(__memleak_param_value, kMemTrackSign, strlen(kMemTrackSign)) == 0) { + checkLoadMallocMemTrack = true; + } (void)SystemReadParam(key, buf, &len); #else return; @@ -189,6 +199,17 @@ static bool init_memorytag_function(void* malloc_shared_library_handler, const c return true; } +static bool init_malloc_usable_size_function(void* malloc_shared_library_handler, MallocMallocUsableSizeType* func, const char* prefix) +{ + char symbol[MAX_SYM_NAME_SIZE]; + snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "malloc_usable_size"); + *func = (MallocMallocUsableSizeType)(dlsym(malloc_shared_library_handler, symbol)); + if (*func == NULL) { + return false; + } + return true; +} + static bool init_hook_functions(void* shared_library_handler, struct MallocDispatchType* table, const char* prefix) { if (!init_malloc_function(shared_library_handler, &table->malloc, prefix)) { @@ -206,6 +227,9 @@ static bool init_hook_functions(void* shared_library_handler, struct MallocDispa if (!init_memorytag_function(shared_library_handler, prefix)) { return false; } + if (!init_malloc_usable_size_function(shared_library_handler, &table->malloc_usable_size, prefix)) { + return false; + } return true; } @@ -314,11 +338,11 @@ static bool is_empty_string(const char* str) return true; } -static void install_ohos_malloc_hook(struct musl_libc_globals* globals) +static void install_ohos_malloc_hook(struct musl_libc_globals* globals, const char* shared_lib, const char* prefix) { volatile void* shared_library_handle = (volatile void *)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire); assert(shared_library_handle == NULL || shared_library_handle == (volatile void*)-1); - shared_library_handle = (volatile void*)load_malloc_hook_shared_library(__malloc_hook_shared_lib, __malloc_hook_function_prefix, &globals->malloc_dispatch_table); + shared_library_handle = (volatile void*)load_malloc_hook_shared_library(shared_lib, prefix, &globals->malloc_dispatch_table); if (shared_library_handle == NULL) { // __musl_log(__MUSL_LOG_ERROR, "Can't load shared library '%s'\n", __malloc_hook_shared_lib); return; @@ -335,7 +359,11 @@ static void install_ohos_malloc_hook(struct musl_libc_globals* globals) static void* init_ohos_malloc_hook() { - install_ohos_malloc_hook(&__musl_libc_globals); + if (checkLoadMallocMemTrack) { + install_ohos_malloc_hook(&__musl_libc_globals, kMemTrackSharedLib, kMemTrackPrefix); + } else { + install_ohos_malloc_hook(&__musl_libc_globals, __malloc_hook_shared_lib, __malloc_hook_function_prefix); + } return NULL; } @@ -442,6 +470,10 @@ __attribute__((constructor(1))) static void __musl_initialize() __hook_mode = STEP_HOOK_MODE; } } + volatile bool hook_disable = atomic_load_explicit(&__hook_enable_hook_flag, memory_order_acquire); + if (!hook_disable && checkLoadMallocMemTrack) { + init_ohos_malloc_hook(); + } __initialize_malloc(); errno = 0; } diff --git a/porting/linux/user/src/hook/musl_preinit_common.c b/porting/linux/user/src/hook/musl_preinit_common.c index 3cf8ec7a77c268a5486a488e1c34a259e683f739..97468fc1ead7c70f8b7982ced6ad451bb96cbe0d 100644 --- a/porting/linux/user/src/hook/musl_preinit_common.c +++ b/porting/linux/user/src/hook/musl_preinit_common.c @@ -12,6 +12,7 @@ struct MallocDispatchType __libc_malloc_default_dispatch = { .free = MuslMalloc(free), .mmap = MuslMalloc(mmap), .munmap = MuslMalloc(munmap), + .malloc_usable_size = MuslMalloc(malloc_usable_size), }; volatile atomic_bool __hook_enable_hook_flag; diff --git a/porting/linux/user/src/hook/musl_preinit_common.h b/porting/linux/user/src/hook/musl_preinit_common.h index c978f29578fd83bd855cef8e1566cce1b288d010..83532626e226d8cc8f02e33548b12a9e0b9789c9 100644 --- a/porting/linux/user/src/hook/musl_preinit_common.h +++ b/porting/linux/user/src/hook/musl_preinit_common.h @@ -11,6 +11,8 @@ extern struct MallocDispatchType __libc_malloc_default_dispatch; extern volatile atomic_bool __hook_enable_hook_flag; +extern bool checkLoadMallocMemTrack; + enum EnumFunc { INITIALIZE_FUNCTION, FINALIZE_FUNCTION, @@ -94,6 +96,9 @@ inline volatile const struct MallocDispatchType* get_current_dispatch_table() #ifdef HOOK_ENABLE volatile const struct MallocDispatchType* ret = (struct MallocDispatchType *)atomic_load_explicit(&__musl_libc_globals.current_dispatch_table, memory_order_acquire); if (ret != NULL) { + if (checkLoadMallocMemTrack) { + return ret; + } if (!__get_global_hook_flag()) { ret = NULL; } diff --git a/porting/linux/user/src/internal/malloc_impl.h b/porting/linux/user/src/internal/malloc_impl.h index 717899fa41b8eba85b6870fca970fbcea0f6244d..3f6d0ddf225dedc0130218c7b4733c86331bb8c2 100644 --- a/porting/linux/user/src/internal/malloc_impl.h +++ b/porting/linux/user/src/internal/malloc_impl.h @@ -95,6 +95,8 @@ hidden void *internal_calloc(size_t m, size_t n); hidden void *internal_realloc(void *p, size_t n); +hidden size_t internal_malloc_usable_size(void *p); + #ifdef MALLOC_RED_ZONE hidden void chunk_checksum_set(struct chunk *c); diff --git a/porting/linux/user/src/malloc/malloc_usable_size.c b/porting/linux/user/src/malloc/malloc_usable_size.c index 1cc8812a20530e02cd6470d5dcb0ab5c4fd1fed5..78315923d65e057f50805b41c06e7e97f2e07a9e 100644 --- a/porting/linux/user/src/malloc/malloc_usable_size.c +++ b/porting/linux/user/src/malloc/malloc_usable_size.c @@ -11,7 +11,16 @@ extern size_t je_malloc_usable_size(void *p); hidden void *(*const __realloc_dep)(void *, size_t) = realloc; +#ifdef HOOK_ENABLE +size_t __libc_malloc_usable_size(void* p) +#else size_t malloc_usable_size(void *p) +#endif +{ + return internal_malloc_usable_size(p); +} + +size_t internal_malloc_usable_size(void* p) { #ifdef USE_JEMALLOC return je_malloc_usable_size(p);