addr2line 如何使用内核 space 调试的虚拟地址?

How does addr2line work with virtual addresses for kernel space debugging?

我正在尝试 addr2line 将“pc”寄存器值从内核 oops (example) 转换为内核代码中的一行。我相信程序计数器的值代表一个虚拟地址。

现在 this post 在 Stack Overflow 上说我们通常提供 addr2line 的偏移量而不是虚拟地址。 VA只能在地址space随机化关闭的情况下使用。这也适用于内核吗?我认为应该。

幻灯片 14 上的

This Embedded Linux Conference talk 也利用程序计数器值跳转到代码行,但我相信这只有在地址 space 随机化关闭时才有效。否则,一旦虚拟内存被初始化,内核可能会随机重定位。在这种情况下,从 oops 中选取的任何虚拟地址对 addr2line 都没有任何意义。这都是理论。我现在有 2 个问题:

  1. 我的理解对吗?如果不对,请指正。
  2. 我们如何关闭内核的地址 space 随机化以便可以预测符号的位置?

是的,你的理解是正确的。

您有多种选择:

  1. 通过使用 CONFIG_RANDOMIZE_BASE=n 极端解决方案构建内核,完全移除 KASLR 支持,如果不是出于开发目的,则不推荐。
  2. 使用命令行参数启动内核 nokaslr。有关详细信息,请参阅 here
  3. 手动计算地址从内核.text段开始的偏移量。没那么容易,需要事先知道基地址或从恐慌信息中推断出来。肯定可以使用一些 grep + objdump + 一些更多的 ELF 工具,但非常烦人且耗时。

注意:当然,第 1 点和第 2 点要求内核使用调试符号进行编译,以便 addr2line 完成其工作。

另请参阅:this Linux kernel doc page