references:
http://fotis.loukos.me/blog/?p=25
Kgdb is a source level debugger for the linux kernel. It requires two machines, one running a kernel compiled with kgdb enabled and the second one running gdb. It can be found atsourceforge and a light version has been merged into the 2.6.26 kernel. There is anarticle at kerneltrap which contains all the appropriate information about this light version and it’s differences from the full one. I am going to describe how you can debug a linux kernel running under VirtualBox using the kgdb-light debugger.
First of all you must define a serial port. Go to the settings of your virtual machine, then at the “Serial Ports” and enable “Port 1″. Use port number COM1, port mode ‘Host Pipe’, check ‘Create Pipe’ and enter a path, e.g. /home/fenggxin/myvm/serila1. You can use another port number, e.g. COM2, but then you’ll have to change the device below to ttyS1, ttyS2 for COM3 etc. Furthermore, you can create the pipe yourself and not automatically using:
At your virtual machine you must have a kernel compiled with the option CONFIG_KGDB. You can find this under the “Kernel debugging” menu. I also advise you to enable the CONFIG_DEBUG_INFO to insert debug symbols.
"It seems that when CONFIG_DEBUG_RODATA is 'y', kgdb is unable toaccess its datastructures required to set a breakpoint.Disabling the config option fixes the problem."
.config like this,
CONFIG_DYNAMIC_PRINTK_DEBUG=y
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
At the host machine you only need to install socat and of course gdb. Socat is a multipurpose relay which can be foundhere. You should also transfer theuncompressed image of the kernel running at the vm. It can be found at the directory where you compiled the kernel and it’s name will be vmlinux.
You are now ready to start. At the host machine run:
You must note the PTY, in this case /dev/pts/4. Now fire gdb and load vmlinux. Then set the remote baud to 115200 and attach to the serial port.
# echo ttyS0,115200 > /sys/module/kgdboc/parameters/kgdboc
You’re ready to start debugging! When you want to break use the Alt-SysRq-G key combination or use
# echo g > /proc/sysrq-trigger
This let target kernel waiting for gdb to start.
now, start gdb to,
push your module chardev.ko to virtualbox,
in virtual machine,
#insmod chardev.ko
#lsmod
chardev 3040 0 - Live 0xd07fd000
In host machine, you need to find out the offset of the text section within the module,
http://freebsd.unixtech.be/doc/en/books/developers-handbook/kerneldebug-kld.html
#objdump --section-headers ./chardev.ko | grep text
1 .text 00000324 00000000 00000000 00000058 2**2
The 2nd method for it is, in virtual machine,
#/sys/module/chardev/sections
#ll -a
#cat .bss #this is address of global begin address
#cat .text #this is address of symbol, when add-symbol-file, can use this address
The fourth hexadecimal field (sixth field overall) is the offset of thetext section within the file. Add this offset to the load address of the module to obtainthe relocation address for the module's code. In our example, we get0xd07fd000 +00000000=0xd07fd000. Use the add-symbol-file command in GDB to tell the debugger about the module:
(kgdb) add-symbol-file /sys/modules/linux/linux.ko 0xd07fd000
add symbol table from file "/sys/modules/linux/linux.ko" at text_addr = 0xc0ae22d0?
(y or n) y
Reading symbols from /sys/modules/linux/linux.ko...done.
(kgdb)
If you want to use kgdbwait to start the debugging when the kernel starts loading, there is a patch for grub,
$ cd $ANDROID/external/grub
$patch -p1 < patchname
compile goldfish kernel, there will be an option in grub menu.
QA:
1. How to modify global variables in gdb
I have global int *buf123 in my code, but when I try to read the value I got message:
(gdb) p buf123Cannot access memory at address 0x480(gdb) p &buf123$46 = (int **) 0x480
Steps:
- 1. Check module section addresses on target, so You can give those in add-symbol-file cmd:
cd /sys/module/ai_char_dev/sections
cat .data
cat .bss
cat .txt
2.
Load symbols in gdb host:
(gdb) add-symbol-file /home/xtomhli/aosp/02_07_11/kernel-goldfish/drivers/android_incubator/ai_char_dev.ko 0xf8470000 -s .bss 0xf8470a94 -s .data 0xf8470908add symbol table from file "/home/xtomhli/aosp/02_07_11/kernel-goldfish/drivers/android_incubator/ai_char_dev.ko" at
.text_addr = 0xf8470000
.bss_addr = 0xf8470a94
.data_addr = 0xf84709083.
Now You can print data:(gdb) p buf123
$3 = (int ) 0xf306aa00
(gdb) p buf123
$4 = 269488144
If for some reason You still cant access those by name, You can always use addresses.
objdump --section-headers ai_char_dev.ko # prints section headers offsets
objdump -t ai_char_dev.ko #prints data location in section (+offset in section)
If You want to access one of variables, for example globalint major do:-
objdump -t ai_char_dev.ko | grep myvarialname # find major variable in output (in my case it's"00000070 l O .bss 00000004 major", so it's located in bss with 0x70 offset)- knowing the address of bss section from "cat /sys/module/ai_char_dev/sections/.bss",
You can access variable by it's address:
(gdb) p *(0xf8470a94 + 0x70)
$37 = 248
modify it,
(gdb) set {int}(
0xf8470a94 + 0x70) = 99modify char buffer,
(gdb) set Message[o]='a'
(gdb) set Message[1]='b'
2.
like this,
(gdb)print i
$1 = < value optimized out >
Add EXTRA_CFLAGS += -g -O0 in your module Makefile, do not optimize your module.
This solution can also resolve the problem that the break point can not stop at the accurate code line.
3.
How to enble Dynamic Debug for goldfish(kernel 2.6.29)
Please refer to
http://cateee.net/lkddb/web-lkddb/DYNAMIC_PRINTK_DEBUG.html
http://lxr.linux.no/#linux+v3.4.4/Documentation/dynamic-debug-howto.txt
本文介绍如何利用kgdb-light调试器在VirtualBox环境下调试Linux内核。首先需配置虚拟机串口,并确保内核支持kgdb。然后安装socat和gdb,通过特定命令设置调试参数,实现内核模块的符号加载及变量修改。

被折叠的 条评论
为什么被折叠?



