mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-07 11:58:41 +03:00
faster backtrace; show predecessor blocks on block overflow
This commit is contained in:
parent
b6e2b6e975
commit
5739714b8d
4 changed files with 20 additions and 16 deletions
16
src/alloc.c
16
src/alloc.c
|
@ -200,7 +200,7 @@ static mi_padding_t* mi_page_decode_padding(const mi_page_t* page, const mi_bloc
|
|||
}
|
||||
|
||||
#if MI_DEBUG_TRACE > 0
|
||||
static void _mi_error_trace(const mi_page_t* page, const mi_block_t* block, const char* msg) {
|
||||
static void _mi_show_block_trace(const mi_page_t* page, const mi_block_t* block, const char* msg) {
|
||||
size_t bsize;
|
||||
size_t delta;
|
||||
mi_padding_t* padding = mi_page_decode_padding(page, block, &delta, &bsize);
|
||||
|
@ -209,7 +209,7 @@ static void _mi_error_trace(const mi_page_t* page, const mi_block_t* block, cons
|
|||
}
|
||||
}
|
||||
#else
|
||||
static void _mi_error_trace(const mi_page_t* page, const mi_block_t* block) {
|
||||
static void _mi_show_block_trace(const mi_page_t* page, const mi_block_t* block) {
|
||||
MI_UNUSED(page); MI_UNUSED(block);
|
||||
}
|
||||
#endif
|
||||
|
@ -252,7 +252,7 @@ static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) {
|
|||
size_t size;
|
||||
size_t wrong;
|
||||
if (mi_unlikely(!mi_verify_padding(page,block,&size,&wrong))) {
|
||||
_mi_error_trace(page, block, NULL);
|
||||
_mi_show_block_trace_with_predecessor(page, block, NULL);
|
||||
_mi_error_message(EFAULT, "buffer overflow in heap block %p of size %zu: write after %zu bytes\n", block, size, wrong );
|
||||
}
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ static void mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, co
|
|||
MI_UNUSED(page); MI_UNUSED(block); MI_UNUSED(min_size);
|
||||
}
|
||||
|
||||
static void _mi_error_trace(const mi_page_t* page, const mi_block_t* block, const char* msg) {
|
||||
static void _mi_show_block_trace(const mi_page_t* page, const mi_block_t* block, const char* msg) {
|
||||
MI_UNUSED(page); MI_UNUSED(block); MI_UNUSED(msg);
|
||||
}
|
||||
#endif
|
||||
|
@ -304,12 +304,12 @@ static const mi_block_t* mi_block_predecessor(const mi_page_t* page, const mi_bl
|
|||
}
|
||||
|
||||
// Used if a free list is corrupted which is usually caused by the previous block(s)
|
||||
void _mi_error_trace_with_predecessor(const mi_page_t* page, const mi_block_t* block, const char* msg) {
|
||||
void _mi_show_block_trace_with_predecessor(const mi_page_t* page, const mi_block_t* block, const char* msg) {
|
||||
const mi_block_t* prev = mi_block_predecessor(page,block);
|
||||
if (prev != NULL) {
|
||||
_mi_error_trace(page, prev, "predecessor block");
|
||||
_mi_show_block_trace(page, prev, "predecessor block");
|
||||
}
|
||||
_mi_error_trace(page, block, msg);
|
||||
_mi_show_block_trace(page, block, msg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -335,7 +335,7 @@ static mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, con
|
|||
mi_list_contains(page, page->local_free, block) ||
|
||||
mi_list_contains(page, mi_page_thread_free(page), block))
|
||||
{
|
||||
_mi_error_trace(page, block, NULL);
|
||||
_mi_show_block_trace(page, block, NULL);
|
||||
_mi_error_message(EAGAIN, "double free detected of block %p with size %zu\n", block, mi_page_usable_size_of(page,block));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -358,7 +358,7 @@ void _mi_stack_trace_capture(void** strace, size_t len, size_t skip) {
|
|||
#include <dbghelp.h>
|
||||
#pragma comment(lib,"dbghelp")
|
||||
void _mi_stack_trace_print(const char* msg, void** strace, size_t len, const mi_block_t* block, size_t bsize, size_t avail) {
|
||||
_mi_fprintf(NULL, NULL, "trace %s at %p of size %zu (%zub total available), backtrace:\n",
|
||||
_mi_fprintf(NULL, NULL, "trace %s at %p of size %zu (%zub usable), allocated at:\n",
|
||||
(msg==NULL ? "block" : msg), block, avail, bsize);
|
||||
HANDLE current_process = GetCurrentProcess();
|
||||
SymInitialize(current_process, NULL, TRUE);
|
||||
|
@ -383,15 +383,18 @@ void _mi_stack_trace_capture(void** strace, size_t len, size_t skip) {
|
|||
if (_mi_preloading()) return;
|
||||
if (!mi_recurse_enter()) return; // needed for pthreads
|
||||
void* trace[MI_TRACE_LEN];
|
||||
backtrace(trace, MI_TRACE_LEN);
|
||||
size_t trace_len = skip + len;
|
||||
if (trace_len > len) { trace_len = MI_TRACE_LEN; }
|
||||
memset(trace,0,trace_len);
|
||||
trace_len = backtrace(trace, trace_len);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
void* p = (i + skip < MI_TRACE_LEN ? trace[i+skip] : NULL);
|
||||
void* p = (i + skip < trace_len ? trace[i+skip] : NULL);
|
||||
strace[i] = p;
|
||||
}
|
||||
mi_recurse_exit();
|
||||
}
|
||||
void _mi_stack_trace_print(const char* msg, void** strace, size_t len, const mi_block_t* block, size_t bsize, size_t avail) {
|
||||
_mi_fprintf(NULL, NULL, "trace %s at %p of size %zu (%zub total available), backtrace:\n",
|
||||
_mi_fprintf(NULL, NULL, "trace %s at %p of size %zu (%zub usable), allocated at:\n",
|
||||
(msg==NULL ? "block" : msg), block, avail, bsize);
|
||||
char** names = backtrace_symbols(strace, len);
|
||||
for (size_t i = 0; i < len && strace[i] != NULL; i++) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue