From aa47541ee53ec73422e9b86d324d285973c142a2 Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 7 Apr 2020 08:51:02 -0700 Subject: [PATCH] add mi_heap_print_json --- include/mimalloc.h | 2 ++ src/heap.c | 43 +++++++++++++++++++++++++++++++++++++ src/options.c | 2 ++ test/main-override-static.c | 43 +------------------------------------ 4 files changed, 48 insertions(+), 42 deletions(-) diff --git a/include/mimalloc.h b/include/mimalloc.h index 876ee89b..e526725e 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -296,6 +296,8 @@ typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_ mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg); +mi_decl_export void mi_heap_print_json(mi_heap_t* heap, mi_output_fun* out, void* arg); + // Experimental mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export bool mi_is_redirected() mi_attr_noexcept; diff --git a/src/heap.c b/src/heap.c index ec22889b..4bfd1b5a 100644 --- a/src/heap.c +++ b/src/heap.c @@ -561,3 +561,46 @@ bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_blocks, mi_block_vis mi_visit_blocks_args_t args = { visit_blocks, visitor, arg }; return mi_heap_visit_areas(heap, &mi_heap_area_visitor, &args); } + +// ----------------------------------------------------------------------- +// Print heap blocks in JSON format +// ----------------------------------------------------------------------- + +typedef struct mi_print_json_s { + size_t area_count; + size_t block_count; + mi_output_fun* out; + void* out_arg; +} mi_print_json_t; + +static bool mi_heap_print_json_visit(const mi_heap_t* heap, const mi_heap_area_t* area, const mi_block_info_t* info, void* arg) { + mi_print_json_t* varg = (mi_print_json_t*)(arg); + if (info==NULL) { + _mi_fprintf(varg->out, varg->out_arg, varg->area_count==0 ? " {" : " ]\n}\n,{"); + varg->area_count++; + varg->block_count = 0; + _mi_fprintf(varg->out, varg->out_arg, "\"page\": %zu, \"start\": 0x%p, \"block_size\": %zu, \"used_size\": %zu,\n \"reserved\": %zu, \"committed\": %zu,", varg->area_count, area->blocks, area->block_size, area->used, area->reserved, area->committed); + _mi_fprintf(varg->out, varg->out_arg, " \"blocks\": [\n"); + } + else { + _mi_fprintf(varg->out, varg->out_arg, varg->block_count==0 ? " {" : " ,{"); + varg->block_count++; + _mi_fprintf(varg->out, varg->out_arg, "\"block\": 0x%p, \"valid\": %s, \"size\": %zu, \"usable_size\": %zu, \"allocated_size\": %zu,\n ", info->block, info->valid ? "true" : "false", info->size, info->usable_size, info->allocated_size); + int lineno; + const char* fname; + void* ret = mi_source_unpack(info->source, &fname, &lineno); + if (fname!=NULL) _mi_fprintf(varg->out, varg->out_arg, "\"source\": \"%s:%i\" }\n", fname, lineno); + else if (ret != NULL) _mi_fprintf(varg->out, varg->out_arg, "\"source\": \"(%p)\" }\n", ret); + else _mi_fprintf(varg->out, varg->out_arg, "\"source\": \"\" }\n"); + } + return true; +} + +void mi_heap_print_json(mi_heap_t* heap, mi_output_fun* out, void* arg) { + if (heap==NULL) heap = mi_heap_get_default(); + mi_print_json_t info = { 0, 0, out, arg }; + _mi_fprintf(info.out, info.out_arg, "{ \"heap\": 0x%p, \"thread_id\": 0x%zx, \"page_count\": %zu", heap, heap->thread_id, heap->page_count); + _mi_fprintf(info.out, info.out_arg, ", \"pages\": [\n"); + mi_heap_visit_blocks(heap, true, &mi_heap_print_json_visit, &info); + _mi_fprintf(info.out, info.out_arg, info.area_count==0 ? "]\n" : " ] }\n] }\n"); +} diff --git a/src/options.c b/src/options.c index 45e619f4..d0cf46cb 100644 --- a/src/options.c +++ b/src/options.c @@ -431,6 +431,7 @@ void* mi_source_unpack(mi_source_t source, const char** pfname, int* plineno) { return NULL; } else if ((source.src & 1) == 1) { +#if (MI_SECURE==0) // do not try to unpack the pointer if in secure mode as we cannot guarantee its correctness. const char* fname = (const char*)(mi_debug_fname_base + ((source.src >> MI_LINE_SHIFT) << MI_INTPTR_SHIFT) ); const int lineno = (source.src & MI_LINE_MASK) >> 1; // check if the file pointer is in range in case it was corrupted @@ -451,6 +452,7 @@ void* mi_source_unpack(mi_source_t source, const char** pfname, int* plineno) { if (lineno > 0 && lineno <= 1000000L && *pfname != NULL) { *plineno = lineno; } +#endif return NULL; } else { diff --git a/test/main-override-static.c b/test/main-override-static.c index 6ed49d27..8aec6358 100644 --- a/test/main-override-static.c +++ b/test/main-override-static.c @@ -6,47 +6,6 @@ #include #include // redefines malloc etc. -#include - -typedef struct mi_visit_info_s { - size_t area_count; - size_t block_count; - mi_output_fun* out; - void* out_arg; -} mi_visit_info_t; - -static bool visit(const mi_heap_t* heap, const mi_heap_area_t* area, const mi_block_info_t* info, void* arg) { - mi_visit_info_t* varg = (mi_visit_info_t*)(arg); - if (info==NULL) { - _mi_fprintf(varg->out, varg->out_arg, varg->area_count==0 ? " {" : " ]\n}\n,{"); - varg->area_count++; - varg->block_count = 0; - _mi_fprintf(varg->out, varg->out_arg, "\"area\": %zu, \"start\": 0x%p, \"block_size\": %zu, \"used_size\": %zu,\n \"reserved\": %zu, \"committed\": %zu,", varg->area_count, area->blocks, area->block_size, area->used, area->reserved, area->committed); - _mi_fprintf(varg->out, varg->out_arg, " \"blocks\": [\n"); - } - else { - _mi_fprintf(varg->out, varg->out_arg, varg->block_count==0 ? " {" : " ,{"); - varg->block_count++; - _mi_fprintf(varg->out, varg->out_arg, "\"block\": 0x%p, \"valid\": %s, \"size\": %zu, \"usable_size\": %zu, \"allocated_size\": %zu,\n ", info->block, info->valid ? "true" : "false", info->size, info->usable_size, info->allocated_size); - int lineno; - const char* fname; - void* ret = mi_source_unpack(info->source, &fname, &lineno); - if (fname!=NULL) _mi_fprintf(varg->out, varg->out_arg, "\"source\": \"%s:%i\" }\n", fname, lineno); - else if (ret != NULL) _mi_fprintf(varg->out, varg->out_arg, "\"source\": \"(%p)\" }\n", ret); - else _mi_fprintf(varg->out, varg->out_arg, "\"source\": \"\" }\n"); - } - return true; -} - -static void mi_heap_to_json(mi_heap_t* heap, mi_output_fun* out, void* arg ) { - if (heap==NULL) heap = mi_heap_get_default(); - mi_visit_info_t info = { 0, 0, out, arg }; - _mi_fprintf(info.out, info.out_arg, "[\n"); - mi_heap_visit_blocks(heap, true, &visit, &info); - _mi_fprintf(info.out, info.out_arg, info.area_count==0 ? "]\n" : " ] }\n]\n"); -} - - static void double_free1(); static void double_free2(); @@ -74,7 +33,7 @@ int main() { free(p2); p2 = malloc(16); p1 = realloc(p1, 32); - mi_heap_to_json(NULL,NULL,NULL); + mi_heap_print_json(NULL,NULL,NULL); free(p1); free(p2); //free(s);