linux – 内核堆栈跟踪到源代码行

给定如下的内核堆栈跟踪,如何确定发生问题的特定代码行?
kernel:  [<ffffffff80009a14>] __link_path_walk+0x173/0xfb9
kernel:  [<ffffffff8002cbec>] mntput_no_expire+0x19/0x89
kernel:  [<ffffffff8000eb94>] link_path_walk+0xa6/0xb2
kernel:  [<ffffffff80063c4f>] __mutex_lock_slowpath+0x60/0x9b
kernel:  [<ffffffff800238de>] __path_lookup_intent_open+0x56/0x97
kernel:  [<ffffffff80063c99>] .text.lock.mutex+0xf/0x14
kernel:  [<ffffffff8001b222>] open_namei+0xea/0x712
kernel:  [<ffffffff8006723e>] do_page_fault+0x4fe/0x874
kernel:  [<ffffffff80027660>] do_filp_open+0x1c/0x38
kernel:  [<ffffffff8001a061>] do_sys_open+0x44/0xbe
kernel:  [<ffffffff8005d28d>] tracesys+0xd5/0xe0

虽然我找到函数调用没有问题 – 但是将__link_path_walk加偏移量转换为实际行号是困难的部分.

假设这是一个标准的分发提供的内核,我知道确切的版本和内部版本号,获取必要的元数据和进行相应的查找的过程是什么?

解决方法

给定带有调试符号的未剥离的vmlinux(通常包含与您的内核版本匹配的“linux-devel”或“linux-headers”包),您可以使用binutils附带的addr2line程序将地址转换为源文件中的行.

考虑这个呼叫追踪:

Call Trace:
 [<ffffffff8107bf5d>] ? finish_task_switch+0x3d/0x120
 [<ffffffff815f3130>] __schedule+0x3b0/0x9d0
 [<ffffffff815f3779>] schedule+0x29/0x70
 [<ffffffff815f2ccc>] schedule_hrtimeout_range_clock.part.24+0xdc/0xf0
 [<ffffffff81076440>] ? hrtimer_get_res+0x50/0x50
 [<ffffffff815f2c6f>] ? schedule_hrtimeout_range_clock.part.24+0x7f/0xf0
 [<ffffffff815f2cf9>] schedule_hrtimeout_range_clock+0x19/0x60
 [<ffffffff815f2d53>] schedule_hrtimeout_range+0x13/0x20
 [<ffffffff811a8aa9>] poll_schedule_timeout+0x49/0x70
 [<ffffffff811aa203>] do_sys_poll+0x423/0x550
 [<ffffffff814eaf8c>] ? sock_recvmsg+0x9c/0xd0
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811a8c50>] ? poll_select_copy_remaining+0x140/0x140
 [<ffffffff811aa3fe>] SyS_poll+0x5e/0x100
 [<ffffffff816015d2>] system_call_fastpath+0x16/0x1b

然后可以找到poll_select_copy_remaining中调用者的地址:

$addr2line -e /tmp/vmlinux ffffffff811a8c50
/tmp/linux-3.15-rc8/fs/select.c:209

相关文章

linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、...
Linux性能观测工具按类别可分为系统级别和进程级别,系统级别...
本文详细介绍了curl命令基础和高级用法,包括跳过https的证书...
本文包含作者工作中常用到的一些命令,用于诊断网络、磁盘占满...
linux的平均负载表示运行态和就绪态及不可中断状态(正在io)的...
CPU上下文频繁切换会导致系统性能下降,切换分为进程切换、线...