利用UML调试内核的方便之处在于我们可以直接使用gdb(前面推荐过cgdb)来进行,但不方便之处在于只能调试与硬件不相干的内核代码。前面有文章描述过UML内核的编译,如果要调试UML内核,我们得选上如下两项,否则调试时将提示找不到符号:
Kernel hacking —>
[*] Compile the kernel with debug info
[*] Compile the kernel with frame pointers
既然UML内核可以当一个应用程序执行,所以和普通的gdb调试并没有什么不同,我们可以直接在gdb里运行,这个无需多说,不过需要提前设置:(gdb) set follow-fork-mode parent,因为在启动的过程中UML会进行fork操作,不做这个设置将导致调试跟丢。如果UML内核已经在执行了,那么可以通过-p来进行attach,此时需要知道UML内核进程的主线程,只有对主线程以及另外少数几个线程才能进行调试,而其它普通应用线程已经被这个主线程监控而无法再被gdb调试。获取UML内核进程的主线程可以执行如下命令:
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@localhost ~]# ps uf | grep linux
root 2946 0.0 0.0 103200 800 pts/0 S+ 15:06 0:00 \_ grep linux
root 1849 1.1 1.1 270320 44844 tty1 S+ 14:49 0:12 \_ ./linux ubda=./rootfs mem=256m
root 1856 0.0 1.1 270320 44844 tty1 S+ 14:49 0:00 \_ ./linux ubda=./rootfs mem=256m
root 1857 0.0 1.1 270320 44844 tty1 S+ 14:49 0:00 \_ ./linux ubda=./rootfs mem=256m
root 1858 0.0 1.1 270320 44844 tty1 S+ 14:49 0:00 \_ ./linux ubda=./rootfs mem=256m
root 1859 0.0 0.0 3772 1516 tty1 t+ 14:49 0:00 \_ ./linux ubda=./rootfs mem=256m
root 2010 0.0 0.0 2924 500 tty1 t+ 14:49 0:00 \_ ./linux ubda=./rootfs mem=256m
root 2290 0.0 0.0 2976 620 tty1 t+ 14:49 0:00 \_ ./linux ubda=./rootfs mem=256m
root 2592 0.0 0.0 3400 660 tty1 t+ 14:49 0:00 \_ ./linux ubda=./rootfs mem=256m
root 2624 0.0 0.0 3964 1384 tty1 t+ 14:50 0:00 \_ ./linux ubda=./rootfs mem=256m
root 2626 0.0 0.0 4044 1764 tty1 t+ 14:50 0:00 \_ ./linux ubda=./rootfs mem=256m
|
那么主线程的pid为1849,此时可执行“gdb -p 1849”开始调试,如果gdb提示“ptrace: Operation not permitted.”,那么肯定是attach错线程了:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[root@localhost ~]# gdb -p 2624
GNU gdb (GDB) Red Hat Enterprise Linux (7.1-29.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http:
//gnu.org/licenses/gpl.html>
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
"x86_64-redhat-linux-gnu"
.
For bug reporting instructions, please see:
<http:
//www.gnu.org/software/gdb/bugs/>.
Attaching to process 2624
ptrace: Operation not permitted.
(gdb)
|
进入gdb后也需设置(gdb) set follow-fork-mode parent,理由前面已经说过了。
在内核函数__schedule加个断点试试,按c继续后马上被中断(这是当然的):
1
2
3
4
5
6
|
(gdb) c
Continuing.
Breakpoint 1, __schedule () at kernel/sched.c:5015
5015 kernel/sched.c: No such file or directory.
in kernel/sched.c
|
提示没有xxx文件:kernel/sched.c: No such file or directory.,这只是因为gdb没有找到对应的源文件,利用directory命令把内核源码增加gdb的搜索路径即可:
1
2
3
|
(gdb) directory /usr/src/linux-2.6.38.8
Source directories searc
|