mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-01-14 08:37:59 +08:00
add mi_heap_print_json
This commit is contained in:
parent
75053f211a
commit
aa47541ee5
@ -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;
|
||||
|
43
src/heap.c
43
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");
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -6,47 +6,6 @@
|
||||
|
||||
#include <mimalloc.h>
|
||||
#include <mimalloc-override.h> // redefines malloc etc.
|
||||
#include <mimalloc-internal.h>
|
||||
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user