First start GDB in the root directory of your Linux kernel, using the
vmlinux kernel image as file to debug:
bash$ cd <linux-root>
bash$ ${CROSS_COMPILE}gdb vmlinux
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux".
(gdb)
Now attach to the target and start execution with the commands:
(gdb) target remote bdi:2001
Remote debugging using bdi:2001
0x00000100 in ?? ()
(gdb) c
Continuing.
Now the target should boot Linux as usual. Next you need to load your
kernel module on the target:
bash# insmod -m ex_sw.o
Sections: Size Address Align
.this 00000060 cf030000 2**2
.text 000002f4 cf030060 2**2
.rodata 00000134 cf030354 2**2
.data 00000000 cf030488 2**0
.sdata 0000000c cf030488 2**2
.kstrtab 00000085 cf030494 2**0
.bss 00000000 cf030519 2**0
.sbss 00000008 cf03051c 2**2
...
The option
-m
prints out the addresses of the
various code and data segments (
.text,
.data,
.sdata,
.bss,
.sbss
) after relocation. GDB needs these
addresses to know where all the symbols are located. We now
interrupt GDB to load the symbol table of the module as follows:
(gdb) ^C
Program received signal SIGSTOP, Stopped (signal).
...
(gdb) add-symbol-file <path-to-module-dir>/ex_sw.o 0xcf030060\
-s .rodata 0xcf030354\
-s .data 0xcf030488\
-s .sdata 0xcf030488\
-s .bss 0xcf030519\
-s .sbss 0xcf03051c
add symbol table from file "<path-to-module-dir>/ex_sw.o" at
.text_addr = 0xcf030060
.rodata_addr = 0xcf030354
.data_addr = 0xcf030488
.sdata_addr = 0xcf030488
.bss_addr = 0xcf030519
.sbss_addr = 0xcf03051c
(y or n) y
Reading symbols from <path-to-module-dir>/ex_sw.o...done.
Now you can list the source code of the module, set break points or
inspect variables as usual:
(gdb) l fun
61 static RT_TASK *thread;
62
63 static int cpu_used[NR_RT_CPUS];
64
65 static void fun(int t)
66 {
67 unsigned int loops = LOOPS;
68 while(loops--) {
69 cpu_used[hard_cpu_id()]++;
70 rt_leds_set_mask(1,t);
(gdb)
(gdb) b ex_sw.c:69
Breakpoint 1 at 0xcf03007c: file ex_sw.c, line 69.
(gdb) c
Continuing.
Breakpoint 1, fun (t=1) at ex_sw.c:69
69 cpu_used[hard_cpu_id()]++;
(gdb) p ntasks
$1 = 16
(gdb) p stack_size
$2 = 3000
The next section demonstrates a way to
automate the symbol table loading procedure.
The following GDB macros and scripts help you to load kernel modules
into GDB in a half-automatic way. It assumes, that the module on the
target has been installed with the command:
bash# insmod -m my_module.o > my_module.o.map
In your
$HOME
directory you
need the scripts
add-symbol-file.sh and the
GDB startup file
.gdbinit, which are listed
in
10.3. GDB Startup File and Utility Scripts below.
Now you can include the symbol definition into GDB with:
bash$ ${CROSS_COMPILE}gdb vmlinux
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux".
0x00000100 in ?? ()
c
Continuing.
^C
Program received signal SIGSTOP, Stopped (signal).
0xcf02a91c in ?? ()
(gdb) add-module rtai4/examples/sw/ex_sw.o
add symbol table from file "/HHL/8xx/target/home/wolf/rtai4/examples/sw/ex_sw.o" at
.text_addr = 0xcf030060
.rodata_addr = 0xcf030340
.data_addr = 0xcf030464
.sdata_addr = 0xcf030464
.bss_addr = 0xcf0304f5
.sbss_addr = 0xcf0304f8
(gdb) b ex_sw.c:69
Breakpoint 1 at 0xcf03007c: file ex_sw.c, line 69.
(gdb) c
Continuing.
Breakpoint 1, fun (t=0x1) at ex_sw.c:69
69 cpu_used[hard_cpu_id()]++;
(gdb) p/d loops
$2 = 999986939
(gdb) p t
$3 = 0x1
(gdb) d b
Delete all breakpoints? (y or n) y
(gdb) c
Continuing.