关于怎么打开core文件,参见上一篇,这里不罗嗦了。
1) 首先,这个panic跟内存使用越界有关。先来看看导致panic的call trace和寄存器。
RIP: 0010:[<ffffffff81237e71>] [<ffffffff81237e71>] elv_rqhash_add+0x81/0xa0
RSP: 0018:ffff880142c7da68 EFLAGS: 00010002
RAX: ffff88013f9de800 RBX: ffffffdb6ab92554 RCX: ffff88017d619a70
RDX: 0000000000000001 RSI: ffff88017d619a00 RDI: a800000000000000
RBP: ffff880142c7da70 R08: 8000000000000000 R09: 2aa0000000000000
R10: 5500000000000000 R11: 0000000000000000 R12: ffff880134557660
R13: 0000000000000002 R14: 0000000000000000 R15: 0000000000001000
FS: 0000000000000000(0000) GS:ffff880030440000(0000) knlGS:0000000000000000
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 0000000000000009 CR3: 0000000001001000 CR4: 00000000000406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process md16_raid4 (pid: 37296, threadinfo ffff880142c7c000, task ffff8801389080c0)
Stack:
ffff88017d619a00 ffff880142c7daa0 ffffffff81237fc4 ffff880142c7daa0
<0> ffff880134557660 0000000000000000 ffff88017d619a00 ffff880142c7db10
<0> ffffffff8124181b ffff880124abaf00 ffff88012701eda8 ffff880124aba900
Call Trace:
[<ffffffff81237fc4>] elv_merged_request+0x84/0x90
[<ffffffff8124181b>] __make_request+0x29b/0x4b0
[<ffffffffa0003746>] dm_request+0x166/0x230 [dm_mod]
[<ffffffff8123fa92>] generic_make_request+0x1b2/0x4f0
......
2) 经过反汇编分析elv_rqhash_add以及内核代码对照,发现RAX的值应该是一个类型为hlist_head的数组。检查这个数组的第一个成员发现,其first成员是1,对于hlist_head的first来说,这是一个不可能存在的值。
crash> struct hlist_head 0xffff88013f9de800
struct hlist_head {
first = 0x1
}
3) 由于这个hlist_head的内容非法,尝试看这个指针本身是否有误。首先看内存指针本身,然后就是从入口参数开始,逐层找到这个指针,看哪个环节首先出错。
通过汇编分析,能够确定寄存器RSI的值(入口参数)是一个request结构体。
crash> struct request ffff88017d619a00
struct request {
queuelist = {
next = 0xffff880137afd860,
prev = 0xffff88018fb86e60
},
csd = {
list = {
n