Browse Source

Add bh_print_proc_mem() to dump memory info of current process (#1734)

Only support Posix platforms currently, read memory consumption info from
file "/proc/self/status".
liang.he 3 năm trước cách đây
mục cha
commit
eaedceca2f

+ 29 - 8
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:

+ 6 - 0
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)
 {

+ 6 - 0
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;
+}

+ 48 - 0
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;
+}

+ 6 - 0
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;
+}

+ 13 - 0
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

+ 6 - 0
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)
 {

+ 6 - 0
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)
 {

+ 6 - 0
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)
 {

+ 6 - 0
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

+ 6 - 0
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;
+}

+ 6 - 0
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;

+ 26 - 0
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);
+}

+ 8 - 0
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