From: Simon Glass <simon.glass@canonical.com> Add a field to store the caller for each allocation, using the backtrace information. This can be useful when debugging heap corruption. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- common/dlmalloc.c | 8 ++++---- common/mcheck_core.inc.h | 28 +++++++++++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/common/dlmalloc.c b/common/dlmalloc.c index e288d94d433..706c12d9b9a 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -5954,7 +5954,7 @@ void *dlmalloc(size_t bytes) if (!p) return p; - return mcheck_alloc_posthook(p, bytes); + return mcheck_alloc_posthook(p, bytes, NULL); } void dlfree(void *mem) { dlfree_impl(mcheck_free_prehook(mem)); } @@ -5979,7 +5979,7 @@ void *dlrealloc(void *oldmem, size_t bytes) p = dlrealloc_impl(p, newsz); if (!p) return p; - return mcheck_alloc_noclean_posthook(p, bytes); + return mcheck_alloc_noclean_posthook(p, bytes, NULL); } void *dlmemalign(size_t alignment, size_t bytes) @@ -5990,7 +5990,7 @@ void *dlmemalign(size_t alignment, size_t bytes) if (!p) return p; - return mcheck_memalign_posthook(alignment, p, bytes); + return mcheck_memalign_posthook(alignment, p, bytes, NULL); } /* dlpvalloc, dlvalloc redirect to dlmemalign, so they need no wrapping */ @@ -6004,7 +6004,7 @@ void *dlcalloc(size_t n, size_t elem_size) if (!p) return p; - return mcheck_alloc_noclean_posthook(p, n * elem_size); + return mcheck_alloc_noclean_posthook(p, n * elem_size, NULL); } /* mcheck API */ diff --git a/common/mcheck_core.inc.h b/common/mcheck_core.inc.h index c2089add0d6..63dbeaa5f56 100644 --- a/common/mcheck_core.inc.h +++ b/common/mcheck_core.inc.h @@ -73,6 +73,7 @@ // Full test suite can exceed 10000 concurrent allocations #define REGISTRY_SZ 12000 #define CANARY_DEPTH 2 +#define MCHECK_CALLER_LEN 48 // avoid problems with BSS at early stage: static char mcheck_pedantic_flag __section(".data") = 0; @@ -88,6 +89,7 @@ struct mcheck_hdr { size_t size; /* Exact size requested by user. */ size_t aln_skip; /* Ignored bytes, before the mcheck_hdr, to fulfill alignment */ mcheck_canary canary; /* Magic number to check header integrity. */ + char caller[MCHECK_CALLER_LEN]; /* caller info for debugging */ }; static void mcheck_default_abort(enum mcheck_status status, const void *p) @@ -196,7 +198,8 @@ static size_t mcheck_alloc_prehook(size_t sz) } static void *mcheck_allocated_helper(void *altoghether_ptr, size_t customer_sz, - size_t alignment, int clean_content) + size_t alignment, int clean_content, + const char *caller) { const size_t slop = alignment ? mcheck_evaluate_memalign_prefix_size(alignment) - sizeof(struct mcheck_hdr) : 0; @@ -207,6 +210,10 @@ static void *mcheck_allocated_helper(void *altoghether_ptr, size_t customer_sz, hdr->aln_skip = slop; for (i = 0; i < CANARY_DEPTH; ++i) hdr->canary.elems[i] = MAGICWORD; + if (caller) + strlcpy(hdr->caller, caller, MCHECK_CALLER_LEN); + else + hdr->caller[0] = '\0'; char *payload = (char *)&hdr[1]; @@ -239,14 +246,19 @@ static void *mcheck_allocated_helper(void *altoghether_ptr, size_t customer_sz, return payload; } -static void *mcheck_alloc_posthook(void *altoghether_ptr, size_t customer_sz) +static void *mcheck_alloc_posthook(void *altoghether_ptr, size_t customer_sz, + const char *caller) { - return mcheck_allocated_helper(altoghether_ptr, customer_sz, ANY_ALIGNMENT, CLEAN_CONTENT); + return mcheck_allocated_helper(altoghether_ptr, customer_sz, + ANY_ALIGNMENT, CLEAN_CONTENT, caller); } -static void *mcheck_alloc_noclean_posthook(void *altoghether_ptr, size_t customer_sz) +static void *mcheck_alloc_noclean_posthook(void *altoghether_ptr, + size_t customer_sz, + const char *caller) { - return mcheck_allocated_helper(altoghether_ptr, customer_sz, ANY_ALIGNMENT, KEEP_CONTENT); + return mcheck_allocated_helper(altoghether_ptr, customer_sz, + ANY_ALIGNMENT, KEEP_CONTENT, caller); } static size_t mcheck_memalign_prehook(size_t alig, size_t sz) @@ -254,9 +266,11 @@ static size_t mcheck_memalign_prehook(size_t alig, size_t sz) return mcheck_evaluate_memalign_prefix_size(alig) + sz + sizeof(mcheck_canary); } -static void *mcheck_memalign_posthook(size_t alignment, void *altoghether_ptr, size_t customer_sz) +static void *mcheck_memalign_posthook(size_t alignment, void *altoghether_ptr, + size_t customer_sz, const char *caller) { - return mcheck_allocated_helper(altoghether_ptr, customer_sz, alignment, CLEAN_CONTENT); + return mcheck_allocated_helper(altoghether_ptr, customer_sz, alignment, + CLEAN_CONTENT, caller); } static enum mcheck_status mcheck_mprobe(void *ptr) -- 2.43.0