使用gdb做remote调试时,如何装载内核模块的符号表?
在我的环境中调试scsi_mod模块时,发生如下错误,
....
(gdb) disassemble scsi_get_command
No symbol table is loaded. Use the "file" command.
这个符号在scsi_mod.ko文件之中,我用file命令装载了这个文件,
但是错误依旧存在。
此外,我使用gdb vmlinux启动remote调试的,被包含在这个文件中的
符号可以正常的disas。
因为我使用的image文件并不由我自己控制,而是自动编译的结果,所以
我不能给编译过程增加-g选项,这时这个问题似乎变得有点难搞。
但是,我可以拿到System.map和Module.symvers文件,这两个文件似乎
包含了符号和符号的位置。
调试时,应该如何运用这两个文件?大家有没有遇到过此类情况?
谢谢。
--
Adam Jiang
-----------------------------------
e-mail:jiang...@gmail.com
http://www.adamjiang.com
-----------------------------------
_______________________________________________
Linux 内核开发中文邮件列表
Linux-...@zh-kernel.org
http://zh-kernel.org/mailman/listinfo/linux-kernel
Linux 内核开发中文社区: http://zh-kernel.org
如果我记得没错,可以这样:
gdb> add-symbol-file scsi_mod.ko VADDR
VADDR可以通过grep scsi_mod.ko /proc/modules获得。
> 谢谢。
请问你的kgdb是如何搭建的?你是针对什么平台进行调试?
我用kgdb调试ppc架构的板子。链接时不时会出现:
Ignoring packet error, continuing...
Ignoring packet error, continuing...
Ignoring packet error, continuing...
Malformed response to offset query, timeout
有时进到了调试环境,单步时还是会报上边的错,不能继续进行调试。现在特别郁闷
在 2010年6月8日 下午7:39,Adam Jiang <jiang...@gmail.com>写道:
Hello,
>
> 使用gdb做remote调试时,如何装载内核模块的符号表?
> 在我的环境中调试scsi_mod模块时,发生如下错误,
>
> ....
> (gdb) disassemble scsi_get_command
> No symbol table is loaded. Use the "file" command.
>
> 这个符号在scsi_mod.ko文件之中,我用file命令装载了这个文件,
> 但是错误依旧存在。
>
> 此外,我使用gdb vmlinux启动remote调试的,被包含在这个文件中的
> 符号可以正常的disas。
>
> 因为我使用的image文件并不由我自己控制,而是自动编译的结果,所以
> 我不能给编译过程增加-g选项,这时这个问题似乎变得有点难搞。
> 但是,我可以拿到System.map和Module.symvers文件,这两个文件似乎
> 包含了符号和符号的位置。
> 调试时,应该如何运用这两个文件?大家有没有遇到过此类情况?
>
> 谢谢。
>
> --
> Adam Jiang
> -----------------------------------
> e-mail:jiang...@gmail.com <e-mail%3Ajian...@gmail.com>
我是用的serial接口调试。使用kgdboc配置。关键现在感觉是调试不稳定,有时可以链接上,有时连接不上。并且即使连接上,在进入modules中设置的断点后,单步时,又会失去链接,出现:
Ignoring packet error, continuing...
Ignoring packet error, continuing...
Ignoring packet error, continuing...
Malformed response to offset query, timeout
不知道是哪里的原因,之前使用另外一台服务器做位调试主机,suse发行版似乎不出现的。
现在换了一个主机,使用dedora。不知道是不是主机的问题?
> e-mail%3Ajian...@gmail.com <e-mail%253Ajia...@gmail.com>>
> >> e-mail%3Ajian...@gmail.com <e-mail%253Ajia...@gmail.com> <
> e-mail%253Ajia...@gmail.com <e-mail%25253Aji...@gmail.com>>>
Hi, Li Yu.
非常感谢你的回复!
我刚才在实际调试环境中试验了一下,这个方法似乎时对的,唯一有一点点小小的问题就是
lsmod | grep scsi_mod 得到的是这样一个值:
/ # lsmod | grep scsi
scsi_mod 84000 4 sg,libata,usb_storage,sd_mod, Live 0xc017e000
最后一列给出的地址是相对于现在KERNEL的虚拟地址的OFFSET,所以,在gdb中指定这个
地址并不能正确的dump出来符号的内容。需要计算一下实际的虚拟地址才行。我遇到了这样
一个错误:
(gdb) disassemble scsi_get_command
Dump of assembler code for function scsi_get_command:
0xc017edb8 <scsi_get_command+0>: Cannot access memory at
address 0xc017edb8
这个虚拟地址应该怎样计算?
/大头阿当
--
Adam Jiang
-----------------------------------
e-mail:jiang...@gmail.com
http://www.adamjiang.com
-----------------------------------
试试 /sys/module/scsi_mod/sections/.text
谢谢 Wang.
cat /sys/module/scsi_mod/sections/.text
得到的数值和lsmod最后一列一致,看上去时一个offset。
disas还是不成功。
/大头阿当
--
Adam Jiang
-----------------------------------
e-mail:jiang...@gmail.com
http://www.adamjiang.com
-----------------------------------
OK,我找到方法了。
gdb vmlinux
......
add-symbol-file /lib/modules/.../scsi_mod.ko 0xc017e000 -s .data
0xc0191c60 -s .bss 0xc0192600
......
disas scsi_get_command
其中,必须把.text,.data,.bss等各段的具体位置告诉gdb才行,这些地址都可以采用Americo Wang教的方法
cat /proc/modules/scsi_mod/.text 等得到的。
问题解决,谢谢各位。
/大头阿当
--
Adam Jiang
-----------------------------------
e-mail:jiang...@gmail.com
http://www.adamjiang.com
-----------------------------------
Hi, Hong
我在mips上做调试的。用serial接续。
/Adam
>> http://www.adamjiang.com
>> -----------------------------------
>> _______________________________________________
>> Linux 内核开发中文邮件列表
>> Linux-...@zh-kernel.org
>> http://zh-kernel.org/mailman/listinfo/linux-kernel
>> Linux 内核开发中文社区: http://zh-kernel.org
>
--
Adam Jiang
-----------------------------------
e-mail:jiang...@gmail.com
将elf的每个段的地址逐一加入gdb挺烦人,所以,我写了一个脚本做这个事。
它可以输出一个命令字串,拷贝粘贴到gdb命令行,或者重定向到文件,
然后source这个文件都可以。贴到这里跟大家分享一下。
_________________________________________
#!/bin/sh
# file: disas_helper.sh
# author: jiang...@gmail.com
# revision: 2010-06-09
if [ $# != 2 ]; then
echo "$0 objfile modname"
exit 1
fi
if [ ! -f $1 ]; then
echo "cannot find objfile '$1'"
exit 1
fi
if [ ! -d /sys/module/$2/sections ]; then
echo "cannot find module sections '$2'"
exit 1
fi
modname=$2
add_sect()
{
addr=`cat /sys/module/$modname/sections/$1`
if [ $1 == ".text" ]; then
echo "$addr"
else
echo "-s $1 $addr"
fi
}
add_all_sect()
{
for i in `ls -a
/sys/module/$modname/sections/.[abcdefghijklmnopqrstuvwxyz]*`; do
if [ `basename $i` != ".text" ]; then
add_sect `basename $i`;
fi
done;
}
echo "add-symbol-file $1" `add_sect .text` `add_all_the_other_sect`
_________________________________________
这个错误应该与开发主机无关,而仅仅是串口设置的问题,最常见的就是target和host上面的速度不一致,
你试试用下面的命令调整一下串口的速度,然后重启gdb再试验
$ sudo stty ispeed 115200 ospeed 115200 < /dev/ttyUSB0
我这里用的是115200。你看看代码,然后在试验以下别的速度。
希望这个有帮助。
/大头阿当
刚才google了一下这个问题,看来还有其他可能引起错误,其中一个就是gdb的remote
debug协议在target和host两端不匹配引起的。简而言之,就是gdb版本造成的错误。
你可以使用下面的命令确认究竟是不是版本错误引起的,比如
gdb vmlinux
......
(gdb) set debug remote 1
(gdb) target remote /dev/ttyUSB0
这样你可以看到通讯状况,输出结果如下
`/home/rcwf64/workspace/Bug5968/kernel/stblinux-2.6.18/vmlinux' has
changed; re-reading symbols.
Remote debugging using /dev/ttyUSB0
Sending packet: $qSupported#37...Ack
Packet received: qSupported
Packet qSupported (supported-packets) is supported
......
或者
gdb vmlinux
......
(gdb) set debug serial 1
(gdb) target remote /dev/ttyUSB0
都可以看到具体的通讯状况。
/大头阿当