diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 8f28ec4cc..5d286434e 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -258,6 +258,12 @@ WASM_DEFINE_VEC_OWN(module, wasm_module_delete_internal) WASM_DEFINE_VEC_OWN(store, wasm_store_delete) WASM_DEFINE_VEC_OWN(valtype, wasm_valtype_delete) +#ifndef NDEBUG +#define WASM_C_DUMP_PROC_MEM() LOG_PROC_MEM() +#else +#define WASM_C_DUMP_PROC_MEM() (void)0 +#endif + /* Runtime Environment */ own wasm_config_t * wasm_config_new(void) @@ -307,6 +313,14 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts) RuntimeInitArgs init_args = { 0 }; init_args.mem_alloc_type = type; +#ifndef NDEBUG + bh_log_set_verbose_level(BH_LOG_LEVEL_VERBOSE); +#else + bh_log_set_verbose_level(BH_LOG_LEVEL_WARNING); +#endif + + WASM_C_DUMP_PROC_MEM(); + if (type == Alloc_With_Pool) { if (!opts) { return NULL; @@ -337,14 +351,6 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts) goto failed; } -#ifndef NDEBUG - /*DEBUG*/ - bh_log_set_verbose_level(BH_LOG_LEVEL_VERBOSE); -#else - /*VERBOSE*/ - bh_log_set_verbose_level(BH_LOG_LEVEL_WARNING); -#endif - /* create wasm_engine_t */ if (!(engine = malloc_internal(sizeof(wasm_engine_t)))) { goto failed; @@ -358,6 +364,8 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts) engine->ref_count = 1; + WASM_C_DUMP_PROC_MEM(); + RETURN_OBJ(engine, wasm_engine_delete_internal) } @@ -442,6 +450,8 @@ wasm_store_new(wasm_engine_t *engine) { wasm_store_t *store = NULL; + WASM_C_DUMP_PROC_MEM(); + if (!engine || singleton_engine != engine) { return NULL; } @@ -474,6 +484,8 @@ wasm_store_new(wasm_engine_t *engine) goto failed; } + WASM_C_DUMP_PROC_MEM(); + return store; failed: wasm_store_delete(store); @@ -1903,6 +1915,8 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary) bh_assert(singleton_engine); + WASM_C_DUMP_PROC_MEM(); + if (!store || !binary || binary->size == 0 || binary->size > UINT32_MAX) goto quit; @@ -1958,6 +1972,9 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary) goto destroy_lock; module_ex->ref_count = 1; + + WASM_C_DUMP_PROC_MEM(); + return module_ext_to_module(module_ex); destroy_lock: @@ -4453,6 +4470,8 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, return NULL; } + WASM_C_DUMP_PROC_MEM(); + instance = malloc_internal(sizeof(wasm_instance_t)); if (!instance) { goto failed; @@ -4595,6 +4614,8 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, goto failed; } + WASM_C_DUMP_PROC_MEM(); + return instance; failed: diff --git a/core/shared/platform/alios/alios_platform.c b/core/shared/platform/alios/alios_platform.c index 641858737..c9f5f17e6 100644 --- a/core/shared/platform/alios/alios_platform.c +++ b/core/shared/platform/alios/alios_platform.c @@ -40,6 +40,12 @@ void os_free(void *ptr) {} +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + return -1; +} + void * os_mmap(void *hint, size_t size, int prot, int flags) { diff --git a/core/shared/platform/common/freertos/freertos_malloc.c b/core/shared/platform/common/freertos/freertos_malloc.c index 19cf4d5f1..e47a8cce1 100644 --- a/core/shared/platform/common/freertos/freertos_malloc.c +++ b/core/shared/platform/common/freertos/freertos_malloc.c @@ -20,3 +20,9 @@ os_realloc(void *ptr, unsigned size) void os_free(void *ptr) {} + +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + return -1; +} diff --git a/core/shared/platform/common/posix/posix_malloc.c b/core/shared/platform/common/posix/posix_malloc.c index 660d1baae..912998ee0 100644 --- a/core/shared/platform/common/posix/posix_malloc.c +++ b/core/shared/platform/common/posix/posix_malloc.c @@ -22,3 +22,51 @@ os_free(void *ptr) { free(ptr); } + +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + int ret = -1; + FILE *f; + char line[128] = { 0 }; + unsigned int out_idx = 0; + + if (!out || !size) + goto quit; + + f = fopen("/proc/self/status", "r"); + if (!f) { + perror("fopen failed: "); + goto quit; + } + + memset(out, 0, size); + + while (fgets(line, sizeof(line), f)) { +#if WASM_ENABLE_MEMORY_PROFILING != 0 + if (strncmp(line, "Vm", 2) == 0 || strncmp(line, "Rss", 3) == 0) { +#else + if (strncmp(line, "VmRSS", 5) == 0 + || strncmp(line, "RssAnon", 7) == 0) { +#endif + size_t line_len = strlen(line); + if (line_len >= size - 1 - out_idx) + goto close_file; + + /* copying without null-terminated byte */ + memcpy(out + out_idx, line, line_len); + out_idx += line_len; + } + } + + if (ferror(f)) { + perror("fgets failed: "); + goto close_file; + } + + ret = 0; +close_file: + fclose(f); +quit: + return ret; +} \ No newline at end of file diff --git a/core/shared/platform/esp-idf/espidf_malloc.c b/core/shared/platform/esp-idf/espidf_malloc.c index 8fde7c8d3..08ec88305 100644 --- a/core/shared/platform/esp-idf/espidf_malloc.c +++ b/core/shared/platform/esp-idf/espidf_malloc.c @@ -76,3 +76,9 @@ os_free(void *ptr) free(mem_origin); } } + +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + return -1; +} diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index 23f644373..42baad74f 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -977,6 +977,19 @@ os_socket_set_broadcast(bh_socket_t socket, bool is_enabled); int os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled); +/** + * Dump memory information of the current process + * It may have variant implementations in different platforms + * + * @param out the output buffer. It is for sure the return content + * is a c-string which ends up with '\0' + * @param size the size of the output buffer + * + * @return 0 if success, -1 otherwise + */ +int +os_dumps_proc_mem_info(char *out, unsigned int size); + #ifdef __cplusplus } #endif diff --git a/core/shared/platform/linux-sgx/sgx_platform.c b/core/shared/platform/linux-sgx/sgx_platform.c index c0b423d52..b40eaf79c 100644 --- a/core/shared/platform/linux-sgx/sgx_platform.c +++ b/core/shared/platform/linux-sgx/sgx_platform.c @@ -51,6 +51,12 @@ os_free(void *ptr) free(ptr); } +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + return -1; +} + int putchar(int c) { diff --git a/core/shared/platform/nuttx/nuttx_platform.c b/core/shared/platform/nuttx/nuttx_platform.c index 8b8d6d85a..28188420e 100644 --- a/core/shared/platform/nuttx/nuttx_platform.c +++ b/core/shared/platform/nuttx/nuttx_platform.c @@ -38,6 +38,12 @@ os_free(void *ptr) free(ptr); } +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + return -1; +} + void * os_mmap(void *hint, size_t size, int prot, int flags) { diff --git a/core/shared/platform/riot/riot_platform.c b/core/shared/platform/riot/riot_platform.c index 82a846395..a0c38e8c9 100644 --- a/core/shared/platform/riot/riot_platform.c +++ b/core/shared/platform/riot/riot_platform.c @@ -43,6 +43,12 @@ os_free(void *ptr) free(ptr); } +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + return -1; +} + void * os_mmap(void *hint, size_t size, int prot, int flags) { diff --git a/core/shared/platform/rt-thread/rtt_platform.c b/core/shared/platform/rt-thread/rtt_platform.c index 13eb43986..4685e1ea3 100644 --- a/core/shared/platform/rt-thread/rtt_platform.c +++ b/core/shared/platform/rt-thread/rtt_platform.c @@ -88,6 +88,12 @@ os_free(void *ptr) } } +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + return -1; +} + static char wamr_vprint_buf[RT_CONSOLEBUF_SIZE * 2]; int diff --git a/core/shared/platform/windows/win_malloc.c b/core/shared/platform/windows/win_malloc.c index 660d1baae..56aaf9c7b 100644 --- a/core/shared/platform/windows/win_malloc.c +++ b/core/shared/platform/windows/win_malloc.c @@ -22,3 +22,9 @@ os_free(void *ptr) { free(ptr); } + +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + return -1; +} \ No newline at end of file diff --git a/core/shared/platform/zephyr/zephyr_platform.c b/core/shared/platform/zephyr/zephyr_platform.c index 55ad84f42..b4f2e5ec7 100644 --- a/core/shared/platform/zephyr/zephyr_platform.c +++ b/core/shared/platform/zephyr/zephyr_platform.c @@ -85,6 +85,12 @@ void os_free(void *ptr) {} +int +os_dumps_proc_mem_info(char *out, unsigned int size) +{ + return -1; +} + #if 0 struct out_context { int count; diff --git a/core/shared/utils/bh_log.c b/core/shared/utils/bh_log.c index 3e5e95ea9..5e3a5b0f4 100644 --- a/core/shared/utils/bh_log.c +++ b/core/shared/utils/bh_log.c @@ -79,3 +79,29 @@ bh_print_time(const char *prompt) last_time_ms = curr_time_ms; } + +void +bh_print_proc_mem(const char *prompt) +{ + char buf[1024] = { 0 }; + + if (log_verbose_level < BH_LOG_LEVEL_DEBUG) + return; + + if (os_dumps_proc_mem_info(buf, sizeof(buf)) != 0) + return; + + os_printf("%s\n", prompt); + os_printf("===== memory usage =====\n"); + os_printf("%s", buf); + os_printf("==========\n"); + return; +} + +void +bh_log_proc_mem(const char *function, uint32 line) +{ + char prompt[128] = { 0 }; + snprintf(prompt, sizeof(prompt), "[MEM] %s(...) L%u", function, line); + return bh_print_proc_mem(prompt); +} \ No newline at end of file diff --git a/core/shared/utils/bh_log.h b/core/shared/utils/bh_log.h index 1578028b7..e0bc61da2 100644 --- a/core/shared/utils/bh_log.h +++ b/core/shared/utils/bh_log.h @@ -73,6 +73,14 @@ bh_log(LogLevel log_level, const char *file, int line, const char *fmt, ...); void bh_print_time(const char *prompt); +void +bh_print_proc_mem(const char *prompt); + +void +bh_log_proc_mem(const char *function, uint32 line); + +#define LOG_PROC_MEM(...) bh_log_proc_mem(__FUNCTION__, __LINE__) + #ifdef __cplusplus } #endif