Linux kernel 为什么gdb不使用调试信息显示内核的调试符号?

Linux kernel 为什么gdb不使用调试信息显示内核的调试符号?,linux-kernel,gdb,kvm,Linux Kernel,Gdb,Kvm,我正试图学习更多关于内核和驱动程序开发的知识,因此为此,我考虑使用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:

我正试图学习更多关于内核和驱动程序开发的知识,因此为此,我考虑使用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”选项,我可以连接到虚拟机中的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

另一方面,当使用objdump时,可以在vmlinux中找到“printk”,如图所示,gdb在设置断点时不会抱怨缺少符号。
我假设内核的安装进行得很顺利,并且没有报告任何错误,但我仍然无法解释为什么在kallsyms中找不到相应的符号。

另一件我觉得奇怪的事情是,当我通过/proc/kallsyms时,为什么所有的行都以0开头。

你知道gdb为什么不显示任何符号吗?

正如@IanAbbott所建议的,CONFIG_RANDOMIZE_BASE=y(或“nokaslr”内核命令行参数)

已丢失以防止KASLR。

正如@IanAbbott所建议的,CONFIG_RANDOMIZE_BASE=y(或“nokaslr”内核命令行参数)

已丢失以防止KASLR。

/proc/kallsyms出于安全原因,以0显示所有符号。您需要超级用户权限才能查看符号。如果内核构建已配置了
CONFIG\u RANDOMIZE\u BASE=y
选项,您可能还希望使用“nokaslr”内核命令行选项启动内核,以禁用内核地址空间随机化功能,否则符号值将与实际内存地址不匹配。@IanAbbott谢谢,就是这样。如果你想写一个答案,我很乐意投赞成票,并将其标记为解决方案。再次感谢:)/proc/kallsyms出于安全原因显示所有带有0的符号。您需要超级用户权限才能查看符号。如果内核构建已配置了
CONFIG\u RANDOMIZE\u BASE=y
选项,您可能还希望使用“nokaslr”内核命令行选项启动内核,以禁用内核地址空间随机化功能,否则符号值将与实际内存地址不匹配。@IanAbbott谢谢,就是这样。如果你想写一个答案,我很乐意投赞成票,并将其标记为解决方案。再次感谢:)
~$ 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