doc: malloc: Add a section on finding memory leaks
Document the practical workflow for detecting and diagnosing memory leaks in U-Boot, particularly in sandbox builds. This covers: - Using ut_check_delta() in unit tests for leak detection - Comparing heap dumps with malloc_dump_to_file() - Using malloc traffic logging to trace allocations - Verifying debug functions don't affect heap state - A step-by-step practical workflow Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com>
This commit is contained in:
@@ -418,6 +418,99 @@ malloc testing
|
||||
|
||||
Unit tests can use malloc_enable_testing() to simulate allocation failures.
|
||||
|
||||
Finding Memory Leaks
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
U-Boot provides several tools for detecting and diagnosing memory leaks.
|
||||
These techniques are primarily supported on sandbox, which has the full
|
||||
debugging infrastructure enabled by default (``CONFIG_MALLOC_DEBUG``,
|
||||
``CONFIG_MCHECK_HEAP_PROTECTION``) and access to host filesystem functions
|
||||
for writing dump files.
|
||||
|
||||
**Leak detection in unit tests**
|
||||
|
||||
Unit tests can use ``ut_check_delta()`` to detect memory leaks::
|
||||
|
||||
ulong mem_start;
|
||||
|
||||
mem_start = ut_check_delta(0); /* Record starting heap usage */
|
||||
|
||||
/* ... test code that allocates and frees memory ... */
|
||||
|
||||
ut_asserteq(0, ut_check_delta(mem_start)); /* Verify no leak */
|
||||
|
||||
This uses ``mallinfo().uordblks`` to compare heap usage before and after.
|
||||
|
||||
**Heap dump comparison**
|
||||
|
||||
When a leak is detected, use ``malloc_dump()`` to capture heap state before
|
||||
and after the operation. In sandbox builds, ``malloc_dump_to_file()`` writes
|
||||
the dump to a host file for easier comparison::
|
||||
|
||||
malloc_dump_to_file("/tmp/before.txt");
|
||||
|
||||
/* ... operation that may leak ... */
|
||||
|
||||
malloc_dump_to_file("/tmp/after.txt");
|
||||
|
||||
Then compare the dumps to find leaked allocations::
|
||||
|
||||
$ diff /tmp/before.txt /tmp/after.txt
|
||||
|
||||
Or extract just the addresses and sizes for comparison::
|
||||
|
||||
$ awk '{print $1, $2}' /tmp/before.txt | sort > /tmp/b.txt
|
||||
$ awk '{print $1, $2}' /tmp/after.txt | sort > /tmp/a.txt
|
||||
$ comm -13 /tmp/b.txt /tmp/a.txt # Show allocations only in 'after'
|
||||
|
||||
The dump includes caller information when ``CONFIG_MCHECK_HEAP_PROTECTION``
|
||||
is enabled, showing exactly where each leaked allocation originated.
|
||||
|
||||
**Malloc-traffic logging**
|
||||
|
||||
For more detailed analysis, use the malloc-traffic log to record all
|
||||
allocations during an operation::
|
||||
|
||||
malloc_log_start();
|
||||
|
||||
/* ... operation to trace ... */
|
||||
|
||||
malloc_log_stop();
|
||||
malloc_log_to_file("/tmp/malloc_log.txt"); /* Sandbox only */
|
||||
|
||||
The log shows every malloc(), free(), and realloc() call with addresses, sizes,
|
||||
and caller backtraces (if enabled). Search for allocations that were never
|
||||
freed::
|
||||
|
||||
$ grep "alloc" /tmp/malloc_log.txt # Find all allocations
|
||||
$ grep "16ad1290" /tmp/malloc_log.txt # Check if a specific address was freed
|
||||
|
||||
**Verifying debug functions don't allocate**
|
||||
|
||||
When using these debugging functions, verify they don't affect heap state
|
||||
by checking ``malloc_get_info()`` before and after::
|
||||
|
||||
struct malloc_info before, after;
|
||||
|
||||
malloc_get_info(&before);
|
||||
malloc_dump_to_file("/tmp/dump.txt");
|
||||
malloc_get_info(&after);
|
||||
|
||||
/* Verify no allocations occurred */
|
||||
assert(before.malloc_count == after.malloc_count);
|
||||
assert(before.in_use_bytes == after.in_use_bytes);
|
||||
|
||||
**Practical workflow**
|
||||
|
||||
1. Add ``ut_check_delta()`` assertions to your test to detect leaks
|
||||
2. When a leak is detected, add ``malloc_dump_to_file()`` calls before and
|
||||
after the leaking operation
|
||||
3. Run the test and compare the dump files to identify leaked allocations
|
||||
4. Use the caller backtrace in the dump to find the allocation site
|
||||
5. If more detail is needed, enable ``malloc_log_start()`` to trace all
|
||||
allocations during the operation
|
||||
6. Fix the leak and verify the test passes
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user