如何从我的 DKMS 模块获取崩溃回溯中的文件名和行号?
How to get filename and line number in crash backtrace from my DKMS module?
我正在使用 DKMS 在 Debian 发行版上构建一个 Linux 模块,我有一个需要调试的内核冻结。
我已经安装了 crash
命令行工具,带有内核调试符号。
当发生冻结时,我有一个用 crash
命令加载的崩溃文件,我可以从内核跟踪中看到每一行的文件名和行号,但是当它是关于我的模块时,我没有任何文件名,也没有行号。
这是一个例子:
WARNING: active task ffff98d215239e80 on cpu 1 not found in PID hash
KERNEL: /usr/lib/debug/boot/vmlinux-4.19.0-8-amd64
DUMPFILE: /var/crash/202004292108/dump.202004292108 [PARTIAL DUMP]
CPUS: 12
DATE: Wed Apr 29 21:07:00 2020
UPTIME: 00:13:32
LOAD AVERAGE: 0.62, 0.57, 0.37
TASKS: 886
NODENAME: debian
RELEASE: 4.19.0-8-amd64
VERSION: #1 SMP Debian 4.19.98-1+deb10u1 (2020-04-27)
MACHINE: x86_64 (3700 Mhz)
MEMORY: 16 GB
PANIC: "BUG: unable to handle kernel NULL pointer dereference at 0000000000000018"
PID: 15775
COMMAND: "douaned"
TASK: ffff98d215239e80 [THREAD_INFO: ffff98d215239e80]
CPU: 1
STATE: EXIT_DEAD (PANIC)
crash> bt -l
PID: 15775 TASK: ffff98d215239e80 CPU: 1 COMMAND: "douaned"
#0 [ffff98d36e843870] machine_kexec at ffffffff87656967
./debian/build/build_amd64_none_amd64/./arch/x86/include/asm/mem_encrypt.h: 75
#1 [ffff98d36e8438c8] __crash_kexec at ffffffff877213ad
./debian/build/build_amd64_none_amd64/./kernel/kexec_core.c: 958
#2 [ffff98d36e843990] crash_kexec at ffffffff877221fd
./debian/build/build_amd64_none_amd64/./include/linux/compiler.h: 219
#3 [ffff98d36e8439a8] oops_end at ffffffff8762a0ad
./debian/build/build_amd64_none_amd64/./arch/x86/kernel/dumpstack.c: 334
#4 [ffff98d36e8439c8] no_context at ffffffff876653ee
./debian/build/build_amd64_none_amd64/./arch/x86/mm/fault.c: 808
#5 [ffff98d36e843a20] __do_page_fault at ffffffff87665ab2
./debian/build/build_amd64_none_amd64/./arch/x86/mm/fault.c: 1323
#6 [ffff98d36e843a90] page_fault at ffffffff87e0114e
/build/linux-AqT5hv/linux-4.19.98/arch/x86/entry/entry_64.S: 1204
[exception RIP: idr_find]
RIP: ffffffff87d0b860 RSP: ffff98d36e843b40 RFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff98d20e848000 RCX: 0000000000000000
RDX: 000000009456dad9 RSI: 0000000000005807 RDI: 0000000000000008
RBP: ffff98d363bc3ae8 R8: 000000000001421d R9: 00000000917bc5e0
R10: ffff98d36e843bae R11: 0000000000000049 R12: 0000000000000004
R13: ffff98d226491480 R14: ffff98d206f28cfc R15: ffff98d206f28d10
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
./debian/build/build_amd64_none_amd64/./lib/idr.c: 177
#7 [ffff98d36e843b40] find_get_pid at ffffffff8769e846
./debian/build/build_amd64_none_amd64/./include/linux/pid.h: 71
#8 [ffff98d36e843b48] netfiler_packet_hook at ffffffffc1962eda [douane]
#9 [ffff98d36e843ce8] nf_hook_slow at ffffffff87c2eea4
./debian/build/build_amd64_none_amd64/./net/netfilter/core.c: 512
#10 [ffff98d36e843d18] __ip_local_out at ffffffff87c3c8a7
./debian/build/build_amd64_none_amd64/./include/linux/netfilter.h: 248
#11 [ffff98d36e843d70] ip_local_out at ffffffff87c3c927
./debian/build/build_amd64_none_amd64/./net/ipv4/ip_output.c: 123
...
看看第 8 行。
从 DKMS 文档中,我找到了 STRIPE=[#]
配置,我将 no
传递给该配置,以便不删除调试符号(如文档所述),但我仍然没有任何文件名或行号。
谁能告诉我怎样才能让它们显示出来?
我终于明白了!
您首先需要知道您的内核模块文件安装在哪里(douane.ko
在我的例子中,它安装在 /lib/modules/$(uname -r)/updates/dkms/
中),然后在加载崩溃文件后,如图所示在问题中,您需要使用 mod
命令加载模块的调试符号:
crash> mod -s douane /lib/modules/4.19.0-8-amd64/updates/dkms/douane.ko
MODULE NAME SIZE OBJECT FILE
ffffffffc17f8040 douane 28672 /lib/modules/4.19.0-8-amd64/updates/dkms/douane.ko
从现在开始,使用 bt -l
也会显示内核模块源代码中的行号。
我正在使用 DKMS 在 Debian 发行版上构建一个 Linux 模块,我有一个需要调试的内核冻结。
我已经安装了 crash
命令行工具,带有内核调试符号。
当发生冻结时,我有一个用 crash
命令加载的崩溃文件,我可以从内核跟踪中看到每一行的文件名和行号,但是当它是关于我的模块时,我没有任何文件名,也没有行号。
这是一个例子:
WARNING: active task ffff98d215239e80 on cpu 1 not found in PID hash
KERNEL: /usr/lib/debug/boot/vmlinux-4.19.0-8-amd64
DUMPFILE: /var/crash/202004292108/dump.202004292108 [PARTIAL DUMP]
CPUS: 12
DATE: Wed Apr 29 21:07:00 2020
UPTIME: 00:13:32
LOAD AVERAGE: 0.62, 0.57, 0.37
TASKS: 886
NODENAME: debian
RELEASE: 4.19.0-8-amd64
VERSION: #1 SMP Debian 4.19.98-1+deb10u1 (2020-04-27)
MACHINE: x86_64 (3700 Mhz)
MEMORY: 16 GB
PANIC: "BUG: unable to handle kernel NULL pointer dereference at 0000000000000018"
PID: 15775
COMMAND: "douaned"
TASK: ffff98d215239e80 [THREAD_INFO: ffff98d215239e80]
CPU: 1
STATE: EXIT_DEAD (PANIC)
crash> bt -l
PID: 15775 TASK: ffff98d215239e80 CPU: 1 COMMAND: "douaned"
#0 [ffff98d36e843870] machine_kexec at ffffffff87656967
./debian/build/build_amd64_none_amd64/./arch/x86/include/asm/mem_encrypt.h: 75
#1 [ffff98d36e8438c8] __crash_kexec at ffffffff877213ad
./debian/build/build_amd64_none_amd64/./kernel/kexec_core.c: 958
#2 [ffff98d36e843990] crash_kexec at ffffffff877221fd
./debian/build/build_amd64_none_amd64/./include/linux/compiler.h: 219
#3 [ffff98d36e8439a8] oops_end at ffffffff8762a0ad
./debian/build/build_amd64_none_amd64/./arch/x86/kernel/dumpstack.c: 334
#4 [ffff98d36e8439c8] no_context at ffffffff876653ee
./debian/build/build_amd64_none_amd64/./arch/x86/mm/fault.c: 808
#5 [ffff98d36e843a20] __do_page_fault at ffffffff87665ab2
./debian/build/build_amd64_none_amd64/./arch/x86/mm/fault.c: 1323
#6 [ffff98d36e843a90] page_fault at ffffffff87e0114e
/build/linux-AqT5hv/linux-4.19.98/arch/x86/entry/entry_64.S: 1204
[exception RIP: idr_find]
RIP: ffffffff87d0b860 RSP: ffff98d36e843b40 RFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff98d20e848000 RCX: 0000000000000000
RDX: 000000009456dad9 RSI: 0000000000005807 RDI: 0000000000000008
RBP: ffff98d363bc3ae8 R8: 000000000001421d R9: 00000000917bc5e0
R10: ffff98d36e843bae R11: 0000000000000049 R12: 0000000000000004
R13: ffff98d226491480 R14: ffff98d206f28cfc R15: ffff98d206f28d10
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
./debian/build/build_amd64_none_amd64/./lib/idr.c: 177
#7 [ffff98d36e843b40] find_get_pid at ffffffff8769e846
./debian/build/build_amd64_none_amd64/./include/linux/pid.h: 71
#8 [ffff98d36e843b48] netfiler_packet_hook at ffffffffc1962eda [douane]
#9 [ffff98d36e843ce8] nf_hook_slow at ffffffff87c2eea4
./debian/build/build_amd64_none_amd64/./net/netfilter/core.c: 512
#10 [ffff98d36e843d18] __ip_local_out at ffffffff87c3c8a7
./debian/build/build_amd64_none_amd64/./include/linux/netfilter.h: 248
#11 [ffff98d36e843d70] ip_local_out at ffffffff87c3c927
./debian/build/build_amd64_none_amd64/./net/ipv4/ip_output.c: 123
...
看看第 8 行。
从 DKMS 文档中,我找到了 STRIPE=[#]
配置,我将 no
传递给该配置,以便不删除调试符号(如文档所述),但我仍然没有任何文件名或行号。
谁能告诉我怎样才能让它们显示出来?
我终于明白了!
您首先需要知道您的内核模块文件安装在哪里(douane.ko
在我的例子中,它安装在 /lib/modules/$(uname -r)/updates/dkms/
中),然后在加载崩溃文件后,如图所示在问题中,您需要使用 mod
命令加载模块的调试符号:
crash> mod -s douane /lib/modules/4.19.0-8-amd64/updates/dkms/douane.ko
MODULE NAME SIZE OBJECT FILE
ffffffffc17f8040 douane 28672 /lib/modules/4.19.0-8-amd64/updates/dkms/douane.ko
从现在开始,使用 bt -l
也会显示内核模块源代码中的行号。