使用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
-----------------------------------
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
这个虚拟地址应该怎样计算?
/大头阿当
谢谢 Wang.
cat /sys/module/scsi_mod/sections/.text
得到的数值和lsmod最后一列一致,看上去时一个offset。
disas还是不成功。
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 等得到的。
问题解决,谢谢各位。
/大头阿当
Hi, Hong
我在mips上做调试的。用serial接续。
/Adam
>> _______________________________________________
>> Linux 内核开发中文邮件列表
>> Linux-...@zh-kernel.org
>> http://zh-kernel.org/mailman/listinfo/linux-kernel
>> Linux 内核开发中文社区: http://zh-kernel.org
将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`
_________________________________________