2014-02-18 43 views
1

我正在調試一個問題,並在產生崩潰轉儲的同時碰到下面的內核崩潰。在某種程度上,我知道,如何在使用gdb(l *(debug_fucntion + 0x19))命令發生問題的代碼中找到確切的行。在內核崩潰轉儲期間分析CPU寄存器

<1>BUG: unable to handle kernel paging request at ffffc90028213000 
<1>IP: [<ffffffffa0180279>] debug_fucntion+0x19/0x160 [dise] 
<4>PGD 103febe067 PUD 103febf067 PMD fd54e1067 PTE 0 
<4>Oops: 0000 [#1] SMP 
<4>last sysfs file: /sys/kernel/mm/ksm/run 
<4>CPU 7 
<4>Modules linked in: dise(P)(U) ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat xt_CHECKSUM iptable_mangle bridge autofs4 8021q garp stp llc ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 vhost_net macvtap macvlan tun kvm uinput ipmi_devintf power_meter microcode iTCO_wdt iTCO_vendor_support dcdbas sg ses enclosure serio_raw lpc_ich mfd_core i7core_edac edac_core bnx2 ext4 jbd2 mbcache sr_mod cdrom sd_mod crc_t10dif pata_acpi ata_generic ata_piix megaraid_sas dm_mirror dm_region_hash dm_log dm_mod [last unloaded: dise] 
<4> 
<4>Pid: 1126, comm: diseproc Tainted: P  W --------------- 2.6.32-431.el6.x86_64 #1 Dell Inc. PowerEdge R710/0MD99X 
<4>RIP: 0010:[<ffffffffa0180279>] [<ffffffffa0180279>] debug_fucntion+0x19/0x160 [dise] 
<4>RSP: 0018:ffff880435fc5b88 EFLAGS: 00010282 
<4>RAX: 0000000000000000 RBX: 0000000000010000 RCX: ffffc90028213000 
<4>RDX: 0000000000010040 RSI: 0000000000010000 RDI: ffff880fe36a0000 
<4>RBP: ffff880435fc5b88 R08: ffffffffa025d8a3 R09: 0000000000000000 
<4>R10: 0000000000000004 R11: 0000000000000004 R12: 0000000000010040 
<4>R13: 000000000000b101 R14: ffffc90028213010 R15: ffff880fe36a0000 
<4>FS: 00007fbe6040b700(0000) GS:ffff8800618e0000(0000) knlGS:0000000000000000 
<4>CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b 
<4>CR2: ffffc90028213000 CR3: 0000000fc965b000 CR4: 00000000000007e0 
<4>DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 
<4>DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 
<4>Process diseproc (pid: 1126, threadinfo ffff880435fc4000, task ffff8807f8be8ae0) 
<4>Stack: 
<4> ffff880435fc5be8 ffffffffa0180498 0000000081158f46 00000c200000fd26 
<4><d> ffffc90028162000 0000fec635fc5bc8 0000000000000018 ffff881011d80000 
<4><d> ffffc90028162000 ffff8802f18fe440 ffff880fc80b4000 ffff880435fc5cec 
<4>Call Trace: 
<4> [<ffffffffa0180498>] cmd_dump+0x1c8/0x360 [dise] 
<4> [<ffffffffa01978e1>] debug_log_show+0x91/0x160 [dise] 
<4> [<ffffffffa013afb9>] process_debug+0x5a9/0x990 [dise] 
<4> [<ffffffff810792c7>] ? current_fs_time+0x27/0x30 
<4> [<ffffffffa013bc38>] dise_ioctl+0xd8/0x300 [dise] 
<4> [<ffffffff8105a501>] ? hotplug_hrtick+0x21/0x60 
<4> [<ffffffff8119db42>] vfs_ioctl+0x22/0xa0 
<4> [<ffffffff8119dce4>] do_vfs_ioctl+0x84/0x580 
<4> [<ffffffff8119e261>] sys_ioctl+0x81/0xa0 
<4> [<ffffffff810e1e5e>] ? __audit_syscall_exit+0x25e/0x290 
<4> [<ffffffff8100b072>] system_call_fastpath+0x16/0x1b 
<4>Code: be c4 10 e1 48 8b 5d d8 44 01 f0 4c 8b 65 e0 4c 8b 6d e8 4c 8b 75 f0 4c 8b 7d f8 c9 c3 0f 1f 44 00 00 55 48 89 e5 0f 1f 44 00 00 <48> 8b 01 48 c1 e8 3c 83 f8 08 76 0b e8 f6 fb ff ff c9 c3 0f 1f 
<1>RIP [<ffffffffa0180279>] debug_fucntion+0x19/0x160 [dise] 
<4> RSP <ffff880435fc5b88> 
<4>CR2: ffffc90028213000 

問題我已經是

  1. 能否被印刷提供更多的信息了CPU寄存器內容?我如何解碼他們?

  2. 我可以從導致崩潰的崩潰轉儲中知道變量值或數據結構值嗎?

  3. 什麼是「Code:be c4 10 e1 48 8b 5d ...」在這裏告訴我?

回答

0
  1. 和2:這是相當很難找出CPU寄存器如何涉及的參數和變量值。

3:該代碼是彙編代碼。你可以在你的反彙編程序中找到它,並找出發生問題的位置。請注意,有< 48> 8b 01 48 ... - 並且AFAIK陷阱發生在此彙編程序命令處。這意味着您需要通過反彙編代碼來進行調試。如果你用debuggig符號編譯你的程序(模塊),你可以找出問題發生的地方。

1

here ...這對如何調試內核崩潰..請參閱部分Objdump

它告訴它什麼,你可以vmlinux的圖像上使用objdump拆卸您的內核映像良好的文檔。此命令將輸出一個大型的內核源代碼的文本文件...然後,您可以在以前創建的輸出文件中導致EIP的問題grep。 PS:我建議在vmlinux上執行objdump並在本地保存。

8

您必須瞭解您正在彙編級別(而非源代碼)檢查(不調試)。在檢查崩潰轉儲時,您必須牢記這一點。

你必須逐行仔細閱讀你的崩潰轉儲報告,因爲它包含很多信息,這也就是你所得到的。

當你的代碼崩潰時,你必須弄清楚爲什麼發生崩潰轉儲報告和反彙編。在你崩潰轉儲報告

第一行告訴你

BUG: unable to handle kernel paging request at ffffc90028213000 

這意味着你使用的是無效的內存。

Process diseproc (pid: 1126, threadinfo ffff880435fc4000, task ffff8807f8be8ae0) 

告訴你在用戶空間發生了什麼緊急時間。看起來像用戶空間進程diseproc發出一些命令給你的驅動程序,導致崩潰。

非常重要的線是

IP: [<ffffffffa0180279>] debug_fucntion+0x19/0x160 [dise] 

嘗試發出dis debug_function命令拆卸debug_function,找到debug_function+25(0x19十六進制= 12月25日),並環顧四周。與C語言源代碼一起閱讀,瞭解debug_function。通常您可以通過比較callq指令來找到C代碼中的崩潰位置 - 反彙編將顯示被調用函數的可打印名稱。

下,最重要的是呼叫追蹤:

Call Trace: 
[<ffffffffa0180498>] cmd_dump+0x1c8/0x360 [dise] 
[<ffffffffa01978e1>] debug_log_show+0x91/0x160 [dise] 
[<ffffffffa013afb9>] process_debug+0x5a9/0x990 [dise] 
[<ffffffff810792c7>] ? current_fs_time+0x27/0x30 
[<ffffffffa013bc38>] dise_ioctl+0xd8/0x300 [dise] 
[<ffffffff8105a501>] ? hotplug_hrtick+0x21/0x60 
[<ffffffff8119db42>] vfs_ioctl+0x22/0xa0 
[<ffffffff8119dce4>] do_vfs_ioctl+0x84/0x580 
[<ffffffff8119e261>] sys_ioctl+0x81/0xa0 
[<ffffffff810e1e5e>] ? __audit_syscall_exit+0x25e/0x290 
[<ffffffff8100b072>] system_call_fastpath+0x16/0x1b 

閱讀底部到頂部:內核得到的ioctl(從diseproc,明顯),內核調用IOCTL處理dise_ioctlDISE模塊,然後current_fs_timeprocess_debugdebug_log_show,最後cmd_dump

現在你知道了:

  • 代碼路徑:dise_ioctl - >current_fs_time - >process_debug - >debug_log_show - >cmd_dump - >莫名其妙地debug_function
  • C代碼近似的地方導致崩潰
  • 原因死機:訪問無效的內存

有了這個信息,你必須使用你的最後也是最有效的方法 - 思考。試着瞭解哪些變量/結構導致崩潰。也許有些人在你抵達debug_function的時候被釋放了?也許你在指針算術中輸入錯誤?

問題的答案:

  1. 很多時候CPU寄存器值是毫無意義的,因爲它無關,與你的C代碼。只是一些價值觀,指向一些記憶 - 無論如何。是的,有一些非常有用的寄存器,如RIP/EIP和RSP/ESP,但其中大部分都遠離上下文。

  2. 非常不可能。你實際上沒有調試 - 你正在檢查你的轉儲 - 你沒有任何調試環境。

  3. 我同意@ user2699113它只是在來自RIP的指針下的內存內容。

還記得 - 最好的調試工具是你的大腦。

+3

不錯的答案.... +1對於這樣一個乾淨的故障 – Deepthought

+0

@pkumarn您也可以使用崩潰轉儲的崩潰實用程序與內核映像來從中獲取更多的調試信息。 –

+0

感謝您的回覆。在崩潰實用程序中,它們是在崩潰時查看結構值或變量的一種方式嗎?在崩潰實用程序嘗試過mod -S <加載模塊>,然後p *(結構名稱),它拋出錯誤說無法找到。我錯過了什麼嗎? – pkumarn