Thursday, May 9, 2013

Enabling kmemleak on Ubuntu i386 12.04.2 LTS by recompiling the kernel


While debugging a kernel module that we were developing, we wanted a kernel with some hacking options enabled, specially the kmemleak feature. Here is how we got that done. We were using Ubuntu i386 12.04.2 on a VirtualBox guest virtual machine running on a Windows 7 host.
  1. Make sure you have atleast 7GB of free space on your system. While creating the VM, I set my disk size (dynamically expanding) to 20GB.
  2. Also make sure you do this on the latest Long Term Support (LTS) version of the Ubuntu supported at the time.
  3. Install VirtualBox Guest editions if using a VM so that it clipboard sharing is enabled making it easier for you to copy and paste command from the Host OS to Guest OS.
  4. Update the system. This is essential as you need the very latest collection of userpace programs, kernel, and userspace-kernelspace libraries which are know to correctly work together at the time you try this. This is necessary becuase when you download the kernel sources, it will be of the latest kernel which should match the one already running on your system successully with other programs - hence when this kernel is recompiled, nothing else would stop working does to version mismatch:
    1. sudo apt-get install update
    2. sudo apt-get install upgrade
    3. Also install all the update suggested by the GUI update manager
    4. Check the kernel version by executing the command: uname -aMine was: Linux anurag-VirtualBox 3.5.0-28-generic #48~precise1-Ubuntu SMP Wed Apr 24 21:43:05 UTC 2013 i686 i686 i386 GNU/Linux
  5. Install the required tools, libraries and the kernel sources (more than 600MB of download):
    1. sudo apt-get install git-core libncurses5 libncurses5-dev libelf-dev asciidoc binutils-dev linux-source qt3-dev-tools libqt3-mt-dev dpkg-dev fakeroot build-essential crash kexec-tools makedumpfile kernel-wedge kernel-package
    2. sudo apt-get source linux-image-$(uname -r)
    3. sudo apt-get build-dep linux-image-$(uname -r)
  6. If you check your home directory, you will find the following files and directories:
    1. linux-lts-quantal-3.5.0
    2. linux-lts-quantal_3.5.0-28.48~precise1.dsc
    3. linux-lts-quantal_3.5.0-28.48~precise1.tar.gz
  7. Change directory to ~/linux-lts-quantal-3.5.0
  8. Enable permissions on the scripts:
    1. sudo chmod a+x debian/scripts/*
    2. sudo chmod a+x debian/scripts/misc/*
  9. Clean the build directory:
    1. sudo fakeroot debian/rules clean
  10. Edit the configurations and enable the required features
    1. sudo fakeroot debian/rules editconfigs
    2. Ignore configurations for all architectures except for i386/config.flavour.generic - for this architectures, enable the kmemleak option under Kernel Hacking and save the configuration file and exit.
  11. Start the build:
    1. sudo fakeroot debian/rules clean
    2. sudo fakeroot debian/rules binary-headers binary-generic
    3. Compilation will take a few hours
  12. Change directory to ~ (your home directory). There you will find few newly created .deb files:
    1. linux-headers-3.5.0-28_3.5.0-28.48~precise1_all.deb
    2. linux-headers-3.5.0-28-generic_3.5.0-28.48~precise1_i386.deb
    3. linux-image-3.5.0-28-generic_3.5.0-28.48~precise1_i386.deb
  13. Install the kernel image, kernel headers and reboot:
    1. sudo dpkg -i *.deb
    2. sudo reboot
  14. Check if kmemleak has been enabled, execute sudo ls /sys/kernel/debug/kmemleak and if you don't get the error "No such file or directory", it means kmemleak is now enabled
  15. Check the kernel version again using uname -a. The kernel compilation date will now have changed:Linux anurag-VirtualBox 3.5.0-28-generic #48~precise1 SMP Thu May 9 00:13:36 IST 2013 i686 i686 i386 GNU/Linux
Further notes:
  1. Refer to kmemleak.txt in the Documentation directory of linux kernel sources to know how to use Kmemleak:
    http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/Documentation/kmemleak.txt
  2. To check if kmemleak has started after your computer has started, check the kernel messages:
    dmesg | grep kmemleak
    You will see two messages like so:
    [    3.840286] kmemleak: Kernel memory leak detector initialized
    [    3.840364] kmemleak: Automatic memory scanning thread started
  3. If you had selected the kmemleak test module option, you will be able to load that module and artificially create orphan obecjts to test if your kmemleak is working or not:
    sudo insmod /lib/modules/3.5.0-28-generic/kernel/mm/kmemleak-test.ko
  4. Before you can write configuration options (for example to trigger scan: sudo echo "scan" > /sys/kernel/debug/kmemleak), you have to make the file writeable:
    sudo chmod 777 /sys/kernel/debug/kmemleak
    You will have to do this every time after a reboot.
References:

3 comments:

mohit vadera said...

how to do same above steps on android kitkat? please guide me. thank you.

Anurag Chugh said...

@mohit
I havent tried compiling android before.. so I dont have any idea. Although there has to be a similar config file that you could modify to do the same.

If you are talking abut detecting leaks in android Java apps then kmemleak is not relevant to you. Java has automatic garbage collection and it has its own profiling tools that you could use.

kmemleak is only for kernel modules coded in C.
It is also not useful for detecting memory leaks for userspace programs and libraries coded in C.

mohit vadera said...

Thank you for your quick reply and help. Of course I am aware about GC in java but I wanna check kernel level memory leakage in android so, I have only one option that kmemleak. any way let me do some experiment by my own. Do you know any other kernel level memory leakage detector tool? Let me know.

Post a Comment