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”包中),您可以使用addr2line
binutils 中包含的程序將地址轉換為源文件中的行。考慮這個呼叫跟踪:
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