Debug your Linux Kernel Module

My project Douane include Linux Kernel Module (LKM) in order to catch/allow/deny network traffic.

You really have to becareful when developing in the Kernel space.
Also debugging a kernel module is something harder than debugging an application in the user space.

Here I'm going to present the tool I've used, and which helped me a lot: KEDR (KErnel-mode Drivers in Runtime).

KEDR is a free and open source framework under the GPL v2 license which analyse the execution of your kernel module, and when you unload the kernel module output a report of everything found like memory leaks.

Dependencies

In order to be able to compile KEDR you need few things:

$ sudo apt-get install cmake linux-headers-$(uname -r)

Installation

The normal installation procedure would be the following:

$ cd /tmp
$ wget http://kedr.googlecode.com/files/kedr-0.4.1.tar.bz2 -O kedr.tar.bz2
$ mkdir kedr-src
$ tar jxf kedr.tar.bz2 -C kedr-src --strip-components 1
$ mkdir kedr-build/
$ cd kedr-build/
$ cmake ../kedr-src/
$ make
$ sudo make install

But the since the kernel 3.10, KEDR is no more compilable.
The only way to make it working is to compile from sources on google code:

$ sudo apt-get install mercurial
$ cd /tmp
$ hg clone https://code.google.com/p/kedr/ ./kedr-src/
$ mkdir kedr-build/
$ cd kedr-build/
$ cmake ../kedr-src/
$ make
$ sudo make install

Memory leaks detection

I'm going to show you how to detect memory leaks in a LKM.

First of all you need to unload your module if it is currently loaded:

$ sudo rmmod mymodule

Then start KEDR:

$ sudo kedr start mymodule
Starting KEDR...
insmod /usr/local/lib/modules/3.13.0-24-generic/misc/kedr.ko target_name=mymodule
insmod /usr/local/lib/modules/3.13.0-24-generic/misc/kedr_leak_check.ko
insmod /usr/local/lib/modules/3.13.0-24-generic/misc/kedr_lc_common_mm.ko
KEDR started.

Now you can load again your module:

$ sudo modprobe mymodule

As of now, KEDR is looking at your module while it is running.

Then after a while, unload your module and have a look to the output:

$ sudo rmmod mymodule
$ tail /var/log/kern.log
May  3 14:25:56 zUbuntu kernel: [16059.298384] [leak_check] Target module: "mymodule", init area at ffffffffa0005000, core area at ffffffffa04ea000
May  3 14:25:56 zUbuntu kernel: [16059.298398] [leak_check] Totals:
May  3 14:25:56 zUbuntu kernel: [16059.298402] [leak_check] Allocations: 8
May  3 14:25:56 zUbuntu kernel: [16059.298406] [leak_check] Possible leaks: 0
May  3 14:25:56 zUbuntu kernel: [16059.298409] [leak_check] Unallocated frees: 0
May  3 14:25:56 zUbuntu kernel: [16059.298411] [leak_check] ======== end of LeakCheck report ========

So here 8 variable allocation performed and 0 possible leaks, meaning all is correctly freed.