debugging - Linux 内核符号地址/proc/kcore 和/proc/kallsyms 之间不匹配

标签 debugging linux-kernel gdb

由于某种原因,我从/proc/kallsyms 获得的地址和我使用/proc/kcore 调试正在运行的内核的地址是不同的。

# uname -a
Linux localhost.localdomain 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

# rpm -ql kernel-debuginfo-3.10.0-862.14.4.el7.x86_64 | grep vmlinux
/usr/lib/debug/lib/modules/3.10.0-862.14.4.el7.x86_64/vmlinux

# gdb -q /usr/lib/debug/lib/modules/3.10.0-862.14.4.el7.x86_64/vmlinux /proc/kcore
Reading symbols from /usr/lib/debug/usr/lib/modules/3.10.0-862.14.4.el7.x86_64/vmlinux...done.
[New process 1]
Core was generated by `BOOT_IMAGE=/vmlinuz-3.10.0-862.14.4.el7.x86_64 root=/dev/mapper/centos-root ro c'.
#0  0x0000000000000000 in irq_stack_union ()

(gdb) p &init_task
$1 = (struct task_struct *) 0xffffffff81c16480 <init_task>
(gdb) quit

# grep "D init_task" /proc/kallsyms 
ffffffffa0a16480 D init_task

当然,这两个地址都来自同一台计算机,无需重新启动它。

地址不应该匹配吗?为什么会发生这种转变?

0xffffffff81c16480

0xffffffffa0a16480

最佳答案

我最终禁用了 KASLR,将 nokaslr 参数添加到内核命令行。

但是,即使禁用了KASLR,仍然需要修复符号偏移。正如 @Ian 在其中一条评论中建议的那样,我使用了 gdb add-symbol-file 命令。使用文本地址的偏移量加载符号,如下所示:

# grep "D init_task" /proc/kallsyms
ffffffff81c16480 D init_task

# grep " _text" /proc/kallsyms
ffffffff81000000 T _text

# gdb -q -c /proc/kcore
(gdb) add-symbol-file /usr/lib/debug/lib/modules/3.10.0-862.14.4.el7.x86_64/vmlinux 0xffffffff81000000
add symbol table from file "/usr/lib/debug/lib/modules/3.10.0-862.14.4.el7.x86_64/vmlinux" at
    .text_addr = 0x81000000
(y or n) y
Reading symbols from /usr/lib/debug/usr/lib/modules/3.10.0-862.14.4.el7.x86_64/vmlinux...done.

(gdb) p &init_task
$1 = (struct task_struct *) 0xffffffff81c16480 <init_task>

它适用于gdb 7.6.1

无论如何,如果知道如何启用 KASLR,那就太棒了。

关于debugging - Linux 内核符号地址/proc/kcore 和/proc/kallsyms 之间不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55583655/

相关文章:

linux - 程序栈的增长方向到底是什么?

objective-c - 将类转储信息导入 GDB

c - gtk_file_chooser_dialog_new () 中的 g_slice_alloc () 出现段错误

debugging - 如何在 Windows 7 64 位上自动启动调试器来调试 32 位应用程序?

delphi - 我可以只忽略一次异常吗?

linux - 在进程上下文切换的情况下,新进程的虚拟地址空间 (VAS) 是否已加载到 CPU 上下文(CPU 的寄存器)中?

linux - 在哪里可以找到在 linux 2.6.21.5-cfs-v19 上运行的 arm 目标的 gdb

debugging - Paradox (ObjectPal) 应用程序偶尔导致一般保护违规,寻找原因

Java 调试困惑

linux-kernel - 中断上下文和异常上下文有什么区别?