[Concept,18/24] malloc: Add file output for heap dump and malloc log

Message ID 20260103011908.149445-19-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>

Add malloc_dump_to_file() and malloc_log_to_file() functions to write
heap dumps and malloc traffic logs to host files. This is useful for
debugging memory leaks in sandbox by allowing comparison of before/after
heap states with external tools like diff.

These functions are only available in sandbox builds since they use
host-filesystem access.

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

 common/dlmalloc.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
 include/malloc.h  | 22 +++++++++++++++
 2 files changed, 90 insertions(+)
  

Patch

diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 7f00dea6eb1..e47f3c153a2 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -6144,6 +6144,38 @@  void malloc_log_dump(void)
 	malloc_log_impl(log_to_console, NULL);
 }
 
+#if IS_ENABLED(CONFIG_SANDBOX)
+/* File output function for log */
+static void log_to_file(void *ctx, const char *fmt, ...)
+{
+	int fd = *(int *)ctx;
+	char buf[256];
+	va_list args;
+	int len;
+
+	va_start(args, fmt);
+	len = vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
+
+	if (len > 0)
+		os_write(fd, buf, len);
+}
+
+int malloc_log_to_file(const char *fname)
+{
+	int fd;
+
+	fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT | OS_O_TRUNC);
+	if (fd < 0)
+		return fd;
+
+	malloc_log_impl(log_to_file, &fd);
+	os_close(fd);
+
+	return 0;
+}
+#endif
+
 int malloc_log_info(struct mlog_info *info)
 {
 	if (!mlog.buf)
@@ -7481,6 +7513,26 @@  static void dump_to_console(void *ctx, const char *fmt, ...)
 	va_end(args);
 }
 
+#if IS_ENABLED(CONFIG_SANDBOX)
+#include <os.h>
+
+/* File output function for heap dump */
+static void dump_to_file(void *ctx, const char *fmt, ...)
+{
+	int fd = *(int *)ctx;
+	char buf[256];
+	va_list args;
+	int len;
+
+	va_start(args, fmt);
+	len = vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
+
+	if (len > 0)
+		os_write(fd, buf, len);
+}
+#endif
+
 static void malloc_dump_impl(dump_out_fn out, void *ctx)
 {
 	mchunkptr q;
@@ -7568,6 +7620,22 @@  void malloc_dump(void)
 	malloc_dump_impl(dump_to_console, NULL);
 }
 
+#if IS_ENABLED(CONFIG_SANDBOX)
+int malloc_dump_to_file(const char *fname)
+{
+	int fd;
+
+	fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT | OS_O_TRUNC);
+	if (fd < 0)
+		return fd;
+
+	malloc_dump_impl(dump_to_file, &fd);
+	os_close(fd);
+
+	return 0;
+}
+#endif
+
 int initf_malloc(void)
 {
 #if CONFIG_IS_ENABLED(SYS_MALLOC_F)
diff --git a/include/malloc.h b/include/malloc.h
index 4bd6458b70d..3deb90b2a0b 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -712,6 +712,17 @@  void malloc_disable_testing(void);
  */
 void malloc_dump(void);
 
+/**
+ * malloc_dump_to_file() - Write heap dump to a host file
+ *
+ * @fname: Path to the output file on the host filesystem
+ * Return: 0 on success, negative error code on failure
+ *
+ * This is only available in sandbox builds. It writes the same information
+ * as malloc_dump() but to a file instead of the console.
+ */
+int malloc_dump_to_file(const char *fname);
+
 /**
  * malloc_log_start() - Start logging malloc traffic
  *
@@ -733,6 +744,17 @@  void malloc_log_stop(void);
  */
 void malloc_log_dump(void);
 
+/**
+ * malloc_log_to_file() - Write malloc()-traffic log to a host file
+ *
+ * @fname: Path to the output file on the host filesystem
+ * Return: 0 on success, negative error code on failure
+ *
+ * This is only available in sandbox builds. It writes the same information
+ * as malloc_log_dump() but to a file instead of the console.
+ */
+int malloc_log_to_file(const char *fname);
+
 /**
  * enum mlog_type - Type of malloc log entry
  */