From: Simon Glass <simon.glass@canonical.com> It is helpful to test that out-of-memory checks work correctly in code that calls malloc(). Add a simple way to force failure after a given number of malloc() calls. Also add support for realloc() testing (from commit 04894f5ad53). Changes from original commits: - Variable declarations moved to top of U-Boot section (before dlmalloc()) - Adapted to new dlmalloc function names (dlmalloc/dlrealloc vs mALLOc/rEALLOc) Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Sean Anderson <seanga2@gmail.com> Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> (cherry picked from commit 62d638386c17d17b929ad10956c7f60825335a4e) (cherry picked from commit 04894f5ad53cab0ee03eb3bc1cc1682e22f5dd1b) --- common/dlmalloc.c | 24 ++++++++++++++++++++++++ include/malloc.h | 12 ++++++++++++ 2 files changed, 36 insertions(+) diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 9298fc445e4..aacc9b5db3b 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -592,6 +592,9 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP DECLARE_GLOBAL_DATA_PTR; +static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */ + ulong mem_malloc_start; ulong mem_malloc_end; ulong mem_malloc_brk; @@ -4614,6 +4617,11 @@ void* dlmalloc(size_t bytes) { /* Return NULL if not initialized yet */ if (!mem_malloc_start && !mem_malloc_end) return NULL; + + if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) { + if (--malloc_max_allocs < 0) + return NULL; + } #endif /* Basic algorithm: @@ -5328,6 +5336,10 @@ void* dlrealloc(void* oldmem, size_t bytes) { panic("pre-reloc realloc() is not supported"); } #endif + if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) { + if (--malloc_max_allocs < 0) + return NULL; + } #endif void* mem = 0; if (oldmem == 0) { @@ -6491,6 +6503,17 @@ void mem_malloc_init(ulong start, ulong size) #endif } +void malloc_enable_testing(int max_allocs) +{ + malloc_testing = true; + malloc_max_allocs = max_allocs; +} + +void malloc_disable_testing(void) +{ + malloc_testing = false; +} + int initf_malloc(void) { #if CONFIG_IS_ENABLED(SYS_MALLOC_F) @@ -6501,4 +6524,5 @@ int initf_malloc(void) return 0; } + #endif /* __UBOOT__ */ diff --git a/include/malloc.h b/include/malloc.h index 76068032da7..72db7fdb507 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -658,6 +658,18 @@ extern ulong mem_malloc_start; extern ulong mem_malloc_end; extern ulong mem_malloc_brk; +/** + * malloc_enable_testing() - Enable malloc failure testing + * + * @max_allocs: Number of allocations to allow before returning NULL + */ +void malloc_enable_testing(int max_allocs); + +/** + * malloc_disable_testing() - Disable malloc failure testing + */ +void malloc_disable_testing(void); + /** * mem_malloc_init() - Initialize the malloc() heap * -- 2.43.0