Chinaunix

标题: 如何调试FreeBSD内核和内核模块? [打印本页]

作者: ktrudger    时间: 2006-06-19 12:47
标题: 如何调试FreeBSD内核和内核模块?
哪位大侠可以指点一二?
作者: 雨丝风片    时间: 2006-06-19 12:49
http://bbs.chinaunix.net/viewthread.php?tid=702553
作者: 雨丝风片    时间: 2006-06-19 16:49
10.7 Debugging Loadable Modules Using GDB

When debugging a panic that occurred within a module, or using remote GDB against a machine that uses dynamic modules, you need to tell GDB how to obtain symbol information for those modules.

First, you need to build the module(s) with debugging information:

  1. # cd /sys/modules/linux
  2. # make clean; make COPTS=-g
复制代码

If you are using remote GDB, you can run kldstat on the target machine to find out where the module was loaded:

  1. # kldstat
  2. Id Refs Address    Size     Name
  3. 1    4 0xc0100000 1c1678   kernel
  4. 2    1 0xc0a9e000 6000     linprocfs.ko
  5. 3    1 0xc0ad7000 2000     warp_saver.ko
  6. 4    1 0xc0adc000 11000    linux.ko
复制代码

If you are debugging a crash dump, you will need to walk the linker_files list, starting at linker_files->tqh_first and following the link.tqe_next pointers until you find the entry with the filename you are looking for. The address member of that entry is the load address of the module.

Next, you need to find out the offset of the text section within the module:

  1. # objdump --section-headers /sys/modules/linux/linux.ko | grep text
  2.   3 .rel.text     000016e0  000038e0  000038e0  000038e0  2**2
  3. 10 .text         00007f34  000062d0  000062d0  000062d0  2**2
复制代码

The one you want is the .text section, section 10 in the above example. The fourth hexadecimal field (sixth field overall) is the offset of the text section within the file. Add this offset to the load address of the module to obtain the relocation address for the module's code. In our example, we get 0xc0adc000 + 0x62d0 = 0xc0ae22d0. Use the add-symbol-file command in GDB to tell the debugger about the module:

  1. (kgdb) add-symbol-file /sys/modules/linux/linux.ko 0xc0ae22d0
  2. add symbol table from file "/sys/modules/linux/linux.ko" at text_addr = 0xc0ae22d0?
  3. (y or n) y
  4. Reading symbols from /sys/modules/linux/linux.ko...done.
  5. (kgdb)
复制代码

You should now have access to all the symbols in the module.
作者: ktrudger    时间: 2006-06-19 17:18
出现了一个错误:
make COPTS=-g

[root@shyfzx ~/hook]# kldstat
Id Refs Address    Size     Name
1    4 0xc0400000 6aacb4   kernel
2    1 0xc0aab000 58570    acpi.ko
3    1 0xc6253000 2000     hook.ko

[root@shyfzx ~/hook]# objdump --section-headers ./hook.ko | grep text
  4 .text         000000ac  00000450  00000450  00000450  2**2

(kgdb) add-symbol-file ./hook.ko 0xc6253450
add symbol table from file "./hook.ko" at
        .text_addr = 0xc6253450
(y or n) y
Reading symbols from ./hook.ko...(no debugging symbols found)...done.
(kgdb)
作者: ktrudger    时间: 2006-06-19 17:19
是我makefile写的不对?
SRCS=hook.c
KMOD=hook

.include <bsd.kmod.mk>
作者: 雨丝风片    时间: 2006-06-19 17:21
原帖由 ktrudger 于 2006-6-19 17:18 发表
出现了一个错误:
make COPTS=-g

[root@shyfzx ~/hook]# kldstat
Id Refs Address    Size     Name
1    4 0xc0400000 6aacb4   kernel
2    1 0xc0aab000 58570    acpi.ko
3    1 0xc6253000 2000 ...



看看你编译内核模块的时候有没有这句话:
objcopy --strip-debug xxxx.ko

作者: ktrudger    时间: 2006-06-19 17:25
最后一句就是这个:
[root@shyfzx ~/hook]# make COPTS=-g
Warning: Object directory not changed from original /root/hook
@ -> /usr/src/sys
machine -> /usr/src/sys/i386/include
cc -O2 -fno-strict-aliasing -pipe -Werror -D_KERNEL -DKLD_MODULE -nostdinc -I-   -I. -I@ -I@/contrib/altq -I@/../include -I/usr/include -finline-limit=8000 -fno-common  -mno-align-long-strings -mpreferred-stack-boundary=2  -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -ffreestanding -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -fformat-extensions -std=c99 -c hook.c
ld  -d -warn-common -r -d -o hook.kld hook.o
touch export_syms
awk -f /sys/conf/kmod_syms.awk hook.kld  export_syms | xargs -J% objcopy % hook.kld
ld -Bshareable  -d -warn-common -o hook.ko hook.kld
objcopy --strip-debug hook.ko
作者: mingyanguo    时间: 2006-06-19 17:32
其实,最后还是printf最可靠,虚拟机有时侯有bug很郁闷.前几天用qemu跑pistachio的时候就直接死掉了(也许与我对qemu的修改有关),还是bochs可靠一点,可惜慢的让人郁闷.如果是跟踪执行流程的话,qemu+GDB确实方便,能源代码级的跟踪.
作者: ktrudger    时间: 2006-06-19 17:35
我下载了一个0.81的qemu源码,configure的时候会错。报告少SDL。我已经对这些复杂的依赖关系深恶痛绝,所以也就懒得理它了。
ports目录下好像没有qemu的,呵呵。
ERROR: QEMU requires SDL or Cocoa for graphical output
To build QEMU without graphical output configure with --disable-gfx-check
Note that this will disable all output from the virtual graphics card.
[root@shyfzx ~/soft/qemu-0.8.1]#


[ 本帖最后由 ktrudger 于 2006-6-19 17:40 编辑 ]
作者: ktrudger    时间: 2006-06-19 17:40
忘了加这个试试“--disable-gfx-check”
作者: ktrudger    时间: 2006-06-19 17:42
还是不行,晕
[root@shyfzx ~/soft/qemu-0.8.1]# make
"Makefile", line 4: Need an operator
"Makefile", line 6: Need an operator
"Makefile", line 11: Need an operator
"Makefile", line 13: Need an operator
"Makefile", line 14: Need an operator
"Makefile", line 16: Need an operator
"Makefile", line 18: Need an operator
"Makefile", line 53: Need an operator
"Makefile", line 56: Need an operator
Error expanding embedded variable
作者: 雨丝风片    时间: 2006-06-19 17:47
原帖由 ktrudger 于 2006-6-19 17:25 发表
最后一句就是这个:
[root@shyfzx ~/hook]# make COPTS=-g
Warning: Object directory not changed from original /root/hook
@ -> /usr/src/sys
machine -> /usr/src/sys/i386/include
cc -O2 -fno-s ...


调试符号都给strip掉了,哪儿还有啊?

在你的Makefile里面加上这样一句:
DEBUG_FLAGS = -g

原来的编译信息为:
  1. ld -Bshareable  -d -warn-common -o xxxx.ko xxxx.kld
  2. objcopy --strip-debug xxxx.ko
复制代码


现在的编译信息为:
  1. ld -Bshareable  -d -warn-common -o xxxx.ko.debug xxxx.kld
  2. objcopy --strip-debug xxxx.ko.debug xxxx.ko
复制代码


说明xxxx.ko是去掉调试符号之后的版本,但它在之前会生成一个名叫xxxx.ko.debug的带有调试符号的版本。
作者: mingyanguo    时间: 2006-06-19 17:52
原帖由 ktrudger 于 2006-6-19 17:35 发表
我下载了一个0.81的qemu源码,configure的时候会错。报告少SDL。我已经对这些复杂的依赖关系深恶痛绝,所以也就懒得理它了。
ports目录下好像没有qemu的,呵呵。
ERROR: QEMU requires SDL or Cocoa ...

ports下面有,emulator目录下.
自己编译的话,你的系统中可能有SDL了,你需要自己改configure,把sdl_config改为你的系统中用的SDL config.
作者: ktrudger    时间: 2006-06-19 18:04
哦 这个搞定了。接下来怎么调试呢?
我b func再func处设断点。
但是运行run,似乎是不行啊。

我再运行kgdb前已经将hook.ko装入系统了。
现在怎么再kgdb中调试该模块呢?让该模块运行到断点停止下来?

或者说我再kgdb中如何运行这个模块呢?

我自己摸索看看。

[ 本帖最后由 ktrudger 于 2006-6-19 18:21 编辑 ]
作者: ktrudger    时间: 2006-08-23 11:40
-bash-2.05b# kldload /root/kernel/main.ko
-bash-2.05b# kldstat
Id Refs Address    Size     Name
1    5 0xc0100000 3dfd8c   kernel
2    1 0xc1fd4000 7000     ipfw.ko
4    1 0xc7f43000 7000     bridge.ko
7    1 0xc2075000 15000    linux.ko
8    1 0xc2091000 7000     main.ko
-bash-2.05b# objdump --section-headers /root/kernel/main.ko | grep text
  3 .rel.text     00001058  00001568  00001568  00001568  2**2
  8 .text         00002780  000027b0  000027b0  000027b0  2**2
-bash-2.05b# gdb -k /root/kernel/main.ko
GNU gdb 4.18 (FreeBSD)
Copyright 1998 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 "i386-unknown-freebsd"...Deprecated bfd_read called at /usr/src/gnu/usr.bin/binutils/gdb/../../../../contrib/gdb/gdb/dbxread.c line 2627 in elfstab_build_psymtabs
Deprecated bfd_read called at /usr/src/gnu/usr.bin/binutils/gdb/../../../../contrib/gdb/gdb/dbxread.c line 933 in fill_symbuf

(kgdb) add-symbol-file /root/kernel/main.ko 0xc20937b0
add symbol table from file "/root/kernel/main.ko" at text_addr = 0xc20937b0?
(y or n) y
Reading symbols from /root/kernel/main.ko...done.
(kgdb) l sys_exit
157
158
159     /* exit sytem */
160     static void sys_exit(void)
161     {
163        destroy_dev(ntd_dev);
165        unregister_hook();
(kgdb) b sys_exit
Cannot access memory at address 0xc20938b0.
(kgdb)

作者: ktrudger    时间: 2006-08-23 11:41
怎么回事?
作者: mingyanguo    时间: 2006-08-23 11:47
把你的kernel放到qemu中跑,在启动qemu的时候加上-s选项,启用远程调试。
然后,gdb kernel
在gdb中target remote localhost:1234
就连接到qemu了
作者: ktrudger    时间: 2006-08-23 13:20
qemu支持FreeBSD 4.11吗?
另外kgdb不支持FreeBSD4.11?
作者: ktrudger    时间: 2006-08-23 14:28
超级郁闷啊,FreeBSD 4.11的/usr/ports/emulators下面没有qemu!
FreeBSD也不支持kgdb,那内核怎个调法?
作者: ktrudger    时间: 2006-08-23 15:17
-bash-2.05b# ./configure  --disable-gfx-check
sdl-config: not found
sdl-config: not found
Install prefix    /usr/local
BIOS directory    /usr/local/share/qemu
binary directory  /usr/local/bin
Manual directory  /usr/local/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /root/qemu-0.8.2
C compiler        gcc
Host C compiler   gcc
make              gmake
install           install
host CPU          i386
host big endian   no
target list       i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu arm-softmmu
gprof enabled     no
profiler          no
static build      no
SDL support       no
mingw32 support   no
Adlib support     no
CoreAudio support no
ALSA support      no
DSound support    no
FMOD support      no
kqemu support     yes
Documentation     no
-bash-2.05b# make
"Makefile", line 9: Need an operator
"Makefile", line 11: Need an operator
"Makefile", line 12: Missing dependency operator
"Makefile", line 14: Need an operator
"Makefile", line 19: Need an operator
"Makefile", line 21: Need an operator
"Makefile", line 22: Need an operator
"Makefile", line 24: Need an operator
"Makefile", line 26: Need an operator
"Makefile", line 64: Need an operator
"Makefile", line 67: Need an operator
Error expanding embedded variable.
-bash-2.05b# pwd
/root/qemu-0.8.2
-bash-2.05b#
改用gmake来编译,则会出很多编译错误!

[ 本帖最后由 ktrudger 于 2006-8-23 15:30 编辑 ]
作者: mingyanguo    时间: 2006-08-23 16:19
qemu 支持任何内核,事实上他并不知道调试的是什么内核,只是遵守gdb的远程调试通讯协议。
没有kgdb可以直接用gdb,gdb的时候要用有调试符号的内核,比如生成了 kernel与kernel.debug那么qemu跑的是kernel而gdb要用kernel.debug

qemu还是ports安装好了。更新下ports看看没注意过版本4
作者: mirnshi    时间: 2006-08-23 18:44
这几天熟悉了一下qemu,个人感觉还是不如vmware使用起来方便,毕竟vmware背后有资本支撑。

有关调试内核,我一般都是在vmware下调试功能,调试性能的时候再挪到相应硬件平台上。
如何在vmware下调试内核,可以参考我的博客上的2篇文章,一个是4.x,一个是针对6.x的修订

http://blog.chinaunix.net/u/132/showart.php?id=51273

http://blog.chinaunix.net/u/132/showart.php?id=125802
作者: mingyanguo    时间: 2006-08-24 08:38
原帖由 mirnshi 于 2006-8-23 18:44 发表
这几天熟悉了一下qemu,个人感觉还是不如vmware使用起来方便,毕竟vmware背后有资本支撑。

有关调试内核,我一般都是在vmware下调试功能,调试性能的时候再挪到相应硬件平台上。
如何在vmware下调试内核,可以 ...

这种方式事实上是使用FB自己支持的双机调试,使用qemu的好处是不需要内核的支持,只要编译的时候加上符号表就可以了。qemu确实是有问题的,对于一些引起CPU的reset的异常没有处理,所以kernel有问题的时候qemu有时候会死掉,而且,qemu的单步经常进入中断处理程序,需要patch一下。至于方便则完全是个人习惯问题。我还是喜欢能自己patch一下的东西。
作者: 雨丝风片    时间: 2006-08-24 08:38
原帖由 mirnshi 于 2006-8-23 18:44 发表
这几天熟悉了一下qemu,个人感觉还是不如vmware使用起来方便,毕竟vmware背后有资本支撑。

有关调试内核,我一般都是在vmware下调试功能,调试性能的时候再挪到相应硬件平台上。
如何在vmware下调试内核,可以 ...


“panic 就会慢慢地从你手中消失,如同手中的那片雪花。”

这句写得好!
作者: ktrudger    时间: 2006-08-24 09:04
原帖由 mirnshi 于 2006-8-23 18:44 发表
这几天熟悉了一下qemu,个人感觉还是不如vmware使用起来方便,毕竟vmware背后有资本支撑。

有关调试内核,我一般都是在vmware下调试功能,调试性能的时候再挪到相应硬件平台上。
如何在vmware下调试内核,可以 ...

我刚才看了一下,好多图片看不到,都是红叉。
作者: mirnshi    时间: 2006-08-24 10:00
原帖由 mingyanguo 于 2006-8-24 08:38 发表

这种方式事实上是使用FB自己支持的双机调试,使用qemu的好处是不需要内核的支持,只要编译的时候加上符号表就可以了。qemu确实是有问题的,对于一些引起CPU的reset的异常没有处理,所以kernel有问题的时候qemu有 ...

qemu能仿真出其他的cpu,倒是非常不错的,有时间的时候,可以尝试将freebsd移植到arm上,现在cvs中有关arm的工作记得是在simics上作的。

另问一句,qemu的网卡模拟只有8029稳定吧?8139,我尝试了一下,到82还是不行,网上有补丁,但是还是存在缺陷。不知道你采用什么网卡?
作者: mirnshi    时间: 2006-08-24 10:01
原帖由 ktrudger 于 2006-8-24 09:04 发表

我刚才看了一下,好多图片看不到,都是红叉。

都是文字的,没有什么图片吧
作者: ktrudger    时间: 2006-08-24 10:08
红“X”对应的内容是什么?
1. 配置调试机
X
2. 配置被调试机
X
进入被调试机
按ctrl-alt-esc,进入db状态
X
进入调试机

[ 本帖最后由 ktrudger 于 2006-8-24 10:10 编辑 ]
作者: mingyanguo    时间: 2006-08-24 11:44
原帖由 mirnshi 于 2006-8-24 10:00 发表

qemu能仿真出其他的cpu,倒是非常不错的,有时间的时候,可以尝试将freebsd移植到arm上,现在cvs中有关arm的工作记得是在simics上作的。

另问一句,qemu的网卡模拟只有8029稳定吧?8139,我尝试了一下,到82 ...

我不用网络,没有注意过这方面。因为网络部分对时间有些敏感,所以我对qemu调试网络栈比较悲观,呵呵。
作者: ktrudger    时间: 2006-08-24 16:22
您应使用 config -g 来配置内核, 并在配置中加入 DDB, 并按通常的方法编译。 由于包含了调试信息,这样做得到的编译结果会很大。 将这个内核复制到目标机上, 并使用 strip -x 脱去调试符号, 并使用引导选项 -d 来启动。用于连接调试主机的目标机上, 应为调试串口设备设置 "flags 080"。 现在, 在调试机上,进入目标内核的编译目录, 并启动 gdb:

怎么用-d参数启动内核呢?
还有我输入:
(kgdb) remote target /dev/cuaa1
Remote device not open
这是怎么回事?
我不知道哪里搞错了。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2