Reputation: 14879
I am doing first steps into Linux kernel development.
I have some code producing a .ko
kernel module that I install with insmod
. I would like a way to debug what happens when I install the module but I am facing some difficulties.
I need to debug the call to init_module
. Is this function called when I run insmode
?
I try to use insmod "/my/url/fil.ko" -m
to debug what happens but each time I got error -1 Unknown symbol in module
while in /cat/log/message
I can see the error unknown parameter -m
Do you know if there is a way to debug with GDB?
Upvotes: 3
Views: 4596
Reputation: 1
GDB cannot inherently catch breakpoints on the init and exit functions of a module like it can the other functions that are meant for servicing system calls on a device node (e.g. opening, reading, or writing a device). I suspect it has to do with which portion of the process's address space they are stored in, but I am not sure.
Further complicating the matter is the fact that modules are loaded at randomized addresses each time - regardless of nokaslr or whether they are statically built or dynamically inserted into the kernel (with nokaslr, the core part of the kernel will be loaded into the same address space all the time, but the modules won't). Therefore, you cannot simply load the module, set a breakpoint on the init symbol's current address, and reload the module. However, there is a solution:
Like Ciro says in approach 2 of his answer, you need to set a breakpoint on the kernel core's do_init_module function, which is called every time any module is loaded. Since it is part of that core kernel code I mentioned, gdb will know its correct location. From there, instead of stepping lots of times (possibly hundreds, from my attempt), follow the instructions at this recent webpost I found:
https://sysprogs.com/VisualKernel/documentation/kernelsymbols/
Upvotes: 0
Reputation: 384424
QEMU + GDB step debug module_init
First get kernel module QEMU + GDB debugging in general working before trying out module_init
: How to debug Linux kernel modules with QEMU?
module_init
is harder because we don't know where the kernel module will get loaded before it does.
Then, here are two non-ideal but usable techniques to break into module_init
:
Find the module load address, and reuse it later.
The module load location is deterministic after each boot, so we can find:
the base address of the .text
section: How to get the address of a kernel module that was inserted using insmod?
the location of the module_init
symbol inside the .text
section:
./readelf -s fops.ko | grep myinit
Then, add them up, and tell GDB to break at that point.
Step into the module_init
call.
On kernel 4.16, first break at:
do_init_module
Then step until:
ret = fn();
Then step into that, and you fall inside the module_init
function.
This QEMU + Buildroot setup can be used to conveniently test both of these methods.
Upvotes: 2
Reputation: 531
Yes, the init_module function gets called as soon as you load it to the kernel using insmod. You can just add a line of printk and verify it being printed as soon as you insert the module.
You cannot pass a parameter such as -m to debug the kernel module.
You can only pass parameters that are intended to be handled within the kernel module that you have written, using MODULE_PARAMS.
Upvotes: 4