为什么 gdb 不显示带有调试信息的内核调试符号?
Why does gdb does not show debug symbols of kernel with debug info?
我想了解更多关于内核和驱动程序开发的信息,因此为此我想使用 KVM 和 gdb 与自定义安装的内核 (v5.1.0) 建立调试会话。
内核包含调试信息,这是我使用的一大块 .config:
$ rg -i "(debug|kalls|GDB_SCRIPTS).*=y" .config
205:CONFIG_KALLSYMS=y
206:CONFIG_KALLSYMS_ALL=y
...
225:CONFIG_SLUB_DEBUG=y
...
9620:CONFIG_DEBUG_INFO=y
9623:CONFIG_DEBUG_INFO_DWARF4=y
9624:CONFIG_GDB_SCRIPTS=y
9640:CONFIG_DEBUG_KERNEL=y
...
通过使用“-s”选项,我可以在我的 VM 中连接到 Ubuntu 18.04 内核,但 gdb 不显示任何符号:
Reading symbols from vmlinux...
(gdb) target remote :1234
Remote debugging using :1234
0xffffffff8ea4af66 in ?? ()
(gdb) bt
#0 0xffffffff8ea4af66 in ?? ()
#1 0xffffffff8f603e38 in ?? ()
#2 0xffffffff8ea4abb2 in ?? ()
#3 0x0000000000000000 in ?? ()
(gdb) i t
Ambiguous info command "t": target, tasks, terminal, threads, tp, tracepoints, tvariables, type-printers, types.
(gdb) i threads
Id Target Id Frame
* 1 Thread 1 (CPU#0 [halted ]) 0xffffffff8ea4af66 in ?? ()
2 Thread 2 (CPU#1 [halted ]) 0xffffffff8ea4af66 in ?? ()
(gdb) b printk
Breakpoint 1 at 0xffffffff81101fa3: file /home/ilukic/projects/kernel/linux-stable/kernel/printk/printk.c, line 2030.
(gdb) c
Continuing.
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0xffffffff81101fa3
Command aborted.
(gdb) disassemble 0xffffffff81101f83,100
Dump of assembler code from 0xffffffff81101f83 to 0x64:
End of assembler dump.
(gdb) disassemble 0xffffffff81101f83,+100
Dump of assembler code from 0xffffffff81101f83 to 0xffffffff81101fe7:
0xffffffff81101f83 <kmsg_dump_rewind_nolock+19>: Cannot access memory at address 0xffffffff81101f83
(gdb) disassemble 0xffffffff81101fa3,+10
Dump of assembler code from 0xffffffff81101fa3 to 0xffffffff81101fad:
0xffffffff81101fa3 <printk+0>: Cannot access memory at address 0xffffffff81101fa3
最后,在 VM 上检查 /proc/kallsyms 时(例如从之前的 gdb 会话中搜索 printk 符号),没有找到符号:
~$ cat /proc/kallsyms | grep "t printk"
0000000000000000 t printk_safe_log_store
0000000000000000 t printk_late_init
~$ uname -a
Linux ubuntu18 5.1.0 #2 SMP Tue Nov 12 19:01:21 CET 2019 x86_64 x86_64 x86_64 GNU/Linux
另一方面,当使用 objdump 时,可以在 vmlinux 中找到 "printk" 并且可以看到,gdb 在设置断点时不会抱怨缺少符号。
我假设内核安装顺利,因为没有报告错误,但我仍然无法解释为什么我在 kallsyms 中找不到相应的符号。
另一件我觉得很奇怪的事情是在经历 /proc/kallsyms 时为什么所有的行都以 0 开头。
知道为什么 gdb 不显示任何符号吗?
正如@IanAbbott 所建议的,CONFIG_RANDOMIZE_BASE=y(或"nokaslr" 内核命令行参数)
缺少以防止 KASLR。
我想了解更多关于内核和驱动程序开发的信息,因此为此我想使用 KVM 和 gdb 与自定义安装的内核 (v5.1.0) 建立调试会话。
内核包含调试信息,这是我使用的一大块 .config:
$ rg -i "(debug|kalls|GDB_SCRIPTS).*=y" .config
205:CONFIG_KALLSYMS=y
206:CONFIG_KALLSYMS_ALL=y
...
225:CONFIG_SLUB_DEBUG=y
...
9620:CONFIG_DEBUG_INFO=y
9623:CONFIG_DEBUG_INFO_DWARF4=y
9624:CONFIG_GDB_SCRIPTS=y
9640:CONFIG_DEBUG_KERNEL=y
...
通过使用“-s”选项,我可以在我的 VM 中连接到 Ubuntu 18.04 内核,但 gdb 不显示任何符号:
Reading symbols from vmlinux...
(gdb) target remote :1234
Remote debugging using :1234
0xffffffff8ea4af66 in ?? ()
(gdb) bt
#0 0xffffffff8ea4af66 in ?? ()
#1 0xffffffff8f603e38 in ?? ()
#2 0xffffffff8ea4abb2 in ?? ()
#3 0x0000000000000000 in ?? ()
(gdb) i t
Ambiguous info command "t": target, tasks, terminal, threads, tp, tracepoints, tvariables, type-printers, types.
(gdb) i threads
Id Target Id Frame
* 1 Thread 1 (CPU#0 [halted ]) 0xffffffff8ea4af66 in ?? ()
2 Thread 2 (CPU#1 [halted ]) 0xffffffff8ea4af66 in ?? ()
(gdb) b printk
Breakpoint 1 at 0xffffffff81101fa3: file /home/ilukic/projects/kernel/linux-stable/kernel/printk/printk.c, line 2030.
(gdb) c
Continuing.
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0xffffffff81101fa3
Command aborted.
(gdb) disassemble 0xffffffff81101f83,100
Dump of assembler code from 0xffffffff81101f83 to 0x64:
End of assembler dump.
(gdb) disassemble 0xffffffff81101f83,+100
Dump of assembler code from 0xffffffff81101f83 to 0xffffffff81101fe7:
0xffffffff81101f83 <kmsg_dump_rewind_nolock+19>: Cannot access memory at address 0xffffffff81101f83
(gdb) disassemble 0xffffffff81101fa3,+10
Dump of assembler code from 0xffffffff81101fa3 to 0xffffffff81101fad:
0xffffffff81101fa3 <printk+0>: Cannot access memory at address 0xffffffff81101fa3
最后,在 VM 上检查 /proc/kallsyms 时(例如从之前的 gdb 会话中搜索 printk 符号),没有找到符号:
~$ cat /proc/kallsyms | grep "t printk"
0000000000000000 t printk_safe_log_store
0000000000000000 t printk_late_init
~$ uname -a
Linux ubuntu18 5.1.0 #2 SMP Tue Nov 12 19:01:21 CET 2019 x86_64 x86_64 x86_64 GNU/Linux
另一方面,当使用 objdump 时,可以在 vmlinux 中找到 "printk" 并且可以看到,gdb 在设置断点时不会抱怨缺少符号。
我假设内核安装顺利,因为没有报告错误,但我仍然无法解释为什么我在 kallsyms 中找不到相应的符号。
另一件我觉得很奇怪的事情是在经历 /proc/kallsyms 时为什么所有的行都以 0 开头。
知道为什么 gdb 不显示任何符号吗?
正如@IanAbbott 所建议的,CONFIG_RANDOMIZE_BASE=y(或"nokaslr" 内核命令行参数)
缺少以防止 KASLR。