本文也即《Linux Device Drivers》,LDD3的第四章Debuging Techniques的读书笔记之六,但我们不限于此内容。这章看得比较慢,最近比较懒,而陷入了文档工作中,我决定这章节不会有之七,在之六打住。
一、先获得vmlinux。
二、进入kernel的gdb模式:
$ sudo gdb vmlinux /proc/kcore
GNU gdb Fedora (6.8-29.fc10)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
Core was generated by `ro root=UUID=e57e257e-7340-411c-a6bb-6eb375f5aa8b rhgb quiet'.
[New process 0]
#0 0x00000000 in ?? ()
(gdb) add-symbol-file /home/wei/workspace/learning/kernel_module/scull_debug/scull.ko 0xf9df8000 -s .bss 0xf9dfaa00 -s .data 0xf9df9720
add symbol table from file "/home/wei/workspace/learning/kernel_module/scull_debug/scull.ko" at
.text_addr = 0xf9df8000
.bss_addr = 0xf9dfaa00
.data_addr = 0xf9df9720
(y or n) y
Reading symbols from /workspace/wei/learning/kernel_module/scull_debug/scull.ko...done.
(gdb) p mydev[0]
$1 = {data = 0x0, quantum = 0, qset = 0, size = 0, access_key = 0, sem = {
lock = {raw_lock = {slock = 0}}, count = 1, wait_list = {
next = 0xf9dfaa3c, prev = 0xf9dfaa3c}}, cdev = {kobj = {name = 0x0,
entry = {next = 0xf9dfaa48, prev = 0xf9dfaa48}, parent = 0x0,
kset = 0x0, ktype = 0xc07d97c0, sd = 0x0, kref = {refcount = {
counter = 1}}, state_initialized = 1, state_in_sysfs = 0,
state_add_uevent_sent = 0, state_remove_uevent_sent = 0},
owner = 0xf9df9880, ops = 0xf9df9740, list = {next = 0xf9dfaa70,
prev = 0xf9dfaa70}, dev = 260046848, count = 1}}
(gdb) p mydev[0] //这里通过用户程序写入信息,在执行一次,发现结果相同,gdb给出的是上次结果的缓存
$2 = {data = 0x0, quantum = 0, qset = 0, size = 0, access_key = 0, sem = {
lock = {raw_lock = {slock = 0}}, count = 1, wait_list = {
next = 0xf9dfaa3c, prev = 0xf9dfaa3c}}, cdev = {kobj = {name = 0x0,
entry = {next = 0xf9dfaa48, prev = 0xf9dfaa48}, parent = 0x0,
kset = 0x0, ktype = 0xc07d97c0, sd = 0x0, kref = {refcount = {
counter = 1}}, state_initialized = 1, state_in_sysfs = 0,
state_add_uevent_sent = 0, state_remove_uevent_sent = 0},
owner = 0xf9df9880, ops = 0xf9df9740, list = {next = 0xf9dfaa70,
prev = 0xf9dfaa70}, dev = 260046848, count = 1}}
(gdb) core-file /proc/kcore //更新,flush cache,下次查询,将是实时内容
Core was generated by `ro root=UUID=e57e257e-7340-411c-a6bb-6eb375f5aa8b rhgb quiet'.
[New process 0]
#0 0x00000000 in ?? ()
(gdb) p mydev[0] $3 = {data = 0xee327020, quantum = 1024, qset = 64, size = 1500,
access_key = 0, sem = {lock = {raw_lock = {slock = 2570}}, count = 1,
wait_list = {next = 0xf9dfaa3c, prev = 0xf9dfaa3c}}, cdev = {kobj = {
name = 0x0, entry = {next = 0xf9dfaa48, prev = 0xf9dfaa48},
parent = 0x0, kset = 0x0, ktype = 0xc07d97c0, sd = 0x0, kref = {
refcount = {counter = 1}}, state_initialized = 1, state_in_sysfs = 0,
state_add_uevent_sent = 0, state_remove_uevent_sent = 0},
owner = 0xf9df9880, ops = 0xf9df9740, list = {next = 0xf264df28,
prev = 0xf264df28}, dev = 260046848, count = 1}}
(gdb)
其他调测工具
据说在2.6.25的版本已经将kgdb(另一个debugger)加入mainline中。我查看.config,确实有该选项,但是没有找到相关Documentation。这个是个强悍的工具,某种意义上是kernel自带的debugger,我觉得似乎适合于kernel的调测,而对于kernel module了将可能有些大材小用了。另外还有LTT(Linux Trace Toolkit)的patch,跟踪信息中包含时间,并可提供一段时期内处理事件,不仅可以用来debug,而且可以跟踪性能问题。IBM为x86-32提供动态探针(Dynamic Probes或者DProbes)提供强大的功能,可以加在kernel和用户程序中,不需要rebuild kernel或者重启,是个很好的工具,可以在http://oss.software.ibm.com 下载。