5

I want to debug my kernel module. For that I am trying to put a breakpoint at do_one_initcall in kernel/module.c just before my init_module gets called but it's displaying

Cannot access memory at address 0x802010a0

Below is the Makefile which I am using:

obj-m := hello.o

KDIR=/lib/modules/$(shell uname -r)/build
PWD=$(shell pwd)

EXTRA_CFLAGS += -g

all:
        make -C $(KDIR) M=$(PWD) modules

clean:
        make -C $(KDIR) M=$(PWD) clean

Please suggest me what could be the problem.

wallyk
  • 56,922
  • 16
  • 83
  • 148
cp5662
  • 51
  • 1
  • 3

1 Answers1

9

A loadable kernel module's location in the memory is set only upon insertion of the module. When you set a breakpoint on a module function, gdb consults the module file (.ko) for the address, which is wrong. You need to inform gdb of the actual location of the module.

You can consult this book (chapter 4, Debuggers and related tools section) for more information, but here's a short procedure that I devised for doing that.

  • machine1 is the debugged machine.
  • machine2 is the machine running the debugger.

  1. On machine1, run modpbrobe your_module_name
  2. On machine1, run the following shell commands:
    MODULE_NAME=your_module_name
    MODULE_FILE=$(modinfo $MODULE_NAME| awk '/filename/{print $2}')
    DIR="/sys/module/${MODULE_NAME}/sections/"
    echo add-symbol-file $MODULE_FILE $(cat "$DIR/.text") -s .bss $(cat "$DIR/.bss") -s .data $(cat "$DIR/.data")
    you should get an output similar to the following:
    add-symbol-file /lib/modules/.../your_module_name.ko 0xffffffffa0110000 -s .bss 0xffffffffa011b948 -s .data 0xffffffffa011b6a0
  3. On machine2, run gdb vmlinux.
  4. On machine2, on the gdb console, run the output of the final command in stage 2.
  5. On machine2, on the gdb console, connect to machine1 by running target remote /dev/ttyS0 (assuming your serial port is at ttyS0)
  6. On machine1, run echo g > /proc/sysrq-trigger. The machine will freeze
  7. On machine2, on the gdb console, set the breakpoint as you wish.
  8. Continue debugging. The breakpoint should be triggered when it needs to.
There could be other issues that prevent you from setting the breakpoint, but this is the main hurdle to cross.
Nir
  • 1,406
  • 2
  • 13
  • 20
  • my `insmod` succeeds and i see my `module_init` kprints int he `dmesg`. but my `modprobe` fails. and thus `modinfo` fails as well. could you provide some insight ? – Jay D Oct 05 '12 at 01:25
  • 1
    There could be several reasons. The most trivial one is that modprobe doesn't know your module, as it consults a database, so you can't do `modprobe my_module_file.ko`. Instead, you need to do `modprobe my_module_name` after inserting it to the database with `depmod -a`. For the sake of this purpose though, it doesn't really matter. You know your name and file name, so you can simply use them instead of what the answer suggests. e.g. `MODULE_NAME=my_module_name; MODULE_FILE=my_module_file.ko` – Nir Oct 09 '12 at 17:30
  • A quick tip: you require root to get the cat /sys/module/module-name-here/sections/.* stuff to work.. (else it just displays the value 0x0). – kaiwan Apr 03 '15 at 02:42
  • @Nir isn't `add-symbol-file` supposed to be run on machine 2? I mean isn't this command a gdb command per se? I don't see how it can be run on machine 1. Or am I missing something? – AjB May 23 '17 at 04:05