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/debugYou 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.
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.
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 } }
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).