给定如下的内核堆栈跟踪,如何确定发生问题的特定代码行?
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