Usage

From STLinux 2.3 kernel #122 onwards, the kernel contains a memory leak detection tool called kmemleak.

To enable kernel memory leak checking turn on this kernel configuration option:

Kernel Hacking -> Kernel memory leak detector

and rebuild the kernel and all kernel modules. Boot the system.

Detected memory leaks are reported through debugfs. To see the result, it is necessary to mount a debugfs filesystem on the target, e.g.

   target# mount -t debugfs nodev /sys/kernel/debug

You may find it more convenient to mount it by default from /etc/fstab, by adding this line:

   debug           /sys/kernel/debug          debugfs defaults                        0 0

A report of all potential memory leaks (defined as memory that has been dynamically allocated but to which no pointer remains in memory) can then be viewed in the file /debug/memleak:

target# cat /sys/kernel/debug/memleak
target# cat /sys/kernel/debug/memleak
unreferenced object 0x86c3c9c0 (size 32):
  [<8400473e>] show_cpuinfo
  [<8400473e>] show_cpuinfo
  [<84076f5a>] seq_read
  [<8408d176>] proc_reg_read
  [<84076e6a>] seq_read
  [<8405d6f6>] vfs_read
  [<8405db62>] sys_read
  [<840078f8>] syscall_call
target#

Note that is necessary to cat the file twice before leaks appear - this allows the system to avoid unwanted "false positive" reports. This report shows that 32 bytes were allocated at the address 0x8400473e, in the function show_cpuinfo(), but there is no pointer left in memory that can be used to free them.

Testing

To test the tool, try adding this line:

    kmalloc(32, GFP_KERNEL);

to the function show_cpuinfo() in the file arch/sh/kernel/setup.c. That function will be executed if you cat the file /proc/cpuinfo. Because the pointer return by kmalloc isn't stored anywhere, those 32 bytes have been leaked and will be reported as shown earlier.

Post-processing the results

The address at which the memory was allocated can be resolved to a line using the tool sh4-linux-addr2line:

% sh4-linux-addr2line -e vmlinux 8400473e
/scratch/smithc/git/linux-sh4-2.6.23.y/arch/sh/kernel/setup.c:396

If the symbol names in the output are C++ mangled names, they can be decoded with the tool c++filt. The entire kmemleak output file can be post-processed with a simple script, such as this:

#!/usr/bin/perl
 
open (FILE, $ARGV[0]);
@lines = <FILE>;
close(FILE);
 
foreach $line (@lines)
{
        if ($line =~ /\[/) {
                @bits = split(" ", $line);
                print "  $bits[0] ";
                system("/usr/bin/c++filt $bits[1]");
        } else {
                print $line
        }
}

Extra configuration options

The kernel configuration allows various kmemleak settings to be adjusted, including the callstack depth (8 is the default) and the maximum number of leaks (100 by default).