[Concept,17/24] malloc: Add an option to disable mcheck-backtrace collection

Message ID 20260103011908.149445-18-sjg@u-boot.org
State New
Headers
Series Malloc debugging and test/py improvements |

Commit Message

Simon Glass Jan. 3, 2026, 1:18 a.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Backtrace collection is relatively expensive and can significantly slow
down malloc()-heavy code when mcheck is enabled.

Add a new CONFIG_MCHECK_BACKTRACE option (default y) to allow disabling
backtrace collection while keeping the other mcheck features (canaries,
double-free detection, etc.) enabled. This allows using mcheck with less
overhead when caller information is not needed.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 Kconfig                | 10 ++++++++++
 common/dlmalloc.c      |  8 ++++++++
 doc/develop/malloc.rst |  7 +++++++
 3 files changed, 25 insertions(+)
  

Patch

diff --git a/Kconfig b/Kconfig
index d47077d43bc..a058bd1a2aa 100644
--- a/Kconfig
+++ b/Kconfig
@@ -355,6 +355,16 @@  config MCHECK_HEAP_PROTECTION
 	  significantly increases memory overhead and should only be used for
 	  debugging.
 
+config MCHECK_BACKTRACE
+	bool "Enable backtrace for mcheck caller info"
+	depends on MCHECK_HEAP_PROTECTION
+	default y
+	help
+	  Enable collection of stack backtrace for each allocation. This
+	  records the function/file/line that allocated the memory, useful
+	  for debugging memory leaks. Disable this to reduce the overhead
+	  of mcheck, since backtrace collection is relatively expensive.
+
 config MCHECK_CALLER_LEN
 	int "Length of caller string in mcheck header"
 	depends on MCHECK_HEAP_PROTECTION
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 6f10a980d6e..7f00dea6eb1 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -5960,6 +5960,7 @@  STATIC_IF_MCHECK size_t dlmalloc_usable_size_impl(const void *mem)
 #include <os.h>
 #include "mcheck_core.inc.h"
 
+#if CONFIG_IS_ENABLED(MCHECK_BACKTRACE)
 /* Guard against recursive backtrace calls during malloc */
 static bool in_backtrace __section(".data");
 
@@ -5968,6 +5969,7 @@  static bool in_backtrace __section(".data");
  * Set via malloc_backtrace_skip() before calling panic().
  */
 static bool mcheck_skip_backtrace __section(".data");
+#endif
 
 /* Runtime flag to disable mcheck - allows bypassing heap protection */
 static bool mcheck_disabled __section(".data");
@@ -5979,11 +5981,14 @@  void mcheck_set_disabled(bool disabled)
 
 void malloc_backtrace_skip(bool skip)
 {
+#if CONFIG_IS_ENABLED(MCHECK_BACKTRACE)
 	mcheck_skip_backtrace = skip;
+#endif
 }
 
 static const char *mcheck_caller(void)
 {
+#if CONFIG_IS_ENABLED(MCHECK_BACKTRACE)
 	const char *caller = NULL;
 
 	if (!in_backtrace && !mcheck_skip_backtrace) {
@@ -5992,6 +5997,9 @@  static const char *mcheck_caller(void)
 		in_backtrace = false;
 	}
 	return caller;
+#else
+	return NULL;
+#endif
 }
 
 #if CONFIG_IS_ENABLED(MCHECK_LOG)
diff --git a/doc/develop/malloc.rst b/doc/develop/malloc.rst
index b9ab884d419..776294809b8 100644
--- a/doc/develop/malloc.rst
+++ b/doc/develop/malloc.rst
@@ -130,6 +130,13 @@  Main U-Boot (post-relocation)
     ``malloc dump``. This significantly increases memory overhead and should
     only be used for debugging. Default: n
 
+``CONFIG_MCHECK_BACKTRACE``
+    Bool to enable backtrace collection for mcheck caller information. When
+    enabled (the default), each allocation records a stack backtrace showing
+    where it was made. This is useful for debugging memory leaks but adds
+    overhead to every malloc call. Disable this to reduce mcheck overhead
+    while keeping the canary checks and double-free detection. Default: y
+
 xPL Boot Phases
 ~~~~~~~~~~~~~~~