Cpu 2 $ 0 : 0000000000000000 00000000508080e0 980000004a57e530 980000004a4fac48 $ 4 : ff0000004a57e530 00000000000000d0 980000001fc3a900 980000004a4fab28 $ 8 : 980000004a4faaf8 0000000000000000 980000004a4fac10 980000004a282758 $12 : 00000000508080e1 000000001000001e 98000000020b1d40 fffffffffffffff8 $16 : 980000004a57e528 980000004a4fabe0 0000000000000000 980000004a57e528 $20 : 980000004bc07338 0000005557128054 0000000000000001 000000000000000b $24 : 00000000000008b5 00000055556ba7b8 $28 : 9800000003764000 9800000003767d30 980000004a28d558 98000000020b4dc4 Hi : 0000000000002997 Lo : 0000000000000ddd epc : 98000000020b4de4 anon_vma_prepare+0xb0/0x16c Not tainted ra : 98000000020b4dc4 anon_vma_prepare+0x90/0x16c Status: 508080e3 KX SX UX KERNEL EXL IE Cause : 0000000c BadVA : ff0000004a57e530 PrId : 000c0009 Modules linked in: ossmod tipc cpp_base bootflash util mtdchar bsp_flash_init boardmem boardctrl Process CSMGR_L_COMMON_ (pid: 1146, threadinfo=9800000003764000, task=980000000375f618) Stack : 6800000000000000 0000000000000000 9800000003776250 980000004bc072a0 980000004a4fabe0 98000000020abf8c 980000004bc072a0 980000004a4fabe0 0000000000002250 0000005557128000 000000555712c000 0000000000000001 0000005557128054 980000004bc072a0 980000004bc07300 980000004a4fabe0 980000000375f618 9800000003767eb0 0000000000000001 000000000000000b 000000ffffeaf780 980000000202acb8 0000005500030002 98000000020b22fc 0000000000000000 0000000000000000 980000004a4fabe0 0000000000000802 0000000000000a03 0000000000000000 9800000003ea8868 980000004bc0c028 980000004bc072a0 0000000000000001 000000555712c000 0000000000000003 0000000000000070 0000000000000032 0000005557128000 0000005557128000 ... Call Trace: [<98000000020b4de4>] anon_vma_prepare+0xb0/0x16c [<98000000020abf8c>] __handle_mm_fault+0x718/0x1288 [<980000000202acb8>] do_page_fault+0x228/0x530 [<980000000200b8e4>] ret_from_exception+0x0/0x10
if (likely(!vma->anon_vma)) { vma->anon_vma = anon_vma; list_add_tail(&vma->anon_vma_node, &anon_vma->head);根据反汇编,出错的情景模拟一下:
98000000020b4dc0: 0280202d move a0,s4 98000000020b4dc4: de220078 ld v0,120(s1) 98000000020b4dc8: 14400009 bnez v0,98000000020b9020 <anon_vma_prepare+0xbc> 98000000020b8ffc: 66020008 daddiu v0,s0,8 //步骤1:取head = &anon_vma->head 98000000020b9000: fe300078 sd s0,120(s1) 98000000020b4dd4: dc440008 ld a0,8(v0) //步骤2:取prev = head->prev 98000000020b4dd8: 66230068 daddiu v1,s1,104 98000000020b4ddc: fe220068 sd v0,104(s1) 98000000020b4de0: fc430008 sd v1,8(v0) 98000000020b4de4: fc830000 sd v1,0(a0) //步骤3:将v1的值存放到prev->next,非法地址访问 98000000020b4de8: fc640008 sd a0,8(v1)
理解反汇编时有一个难点,反汇编代码line 5对应着vma->anon_vma = anon_vma,即s0对应着anon_vma的值,那么反汇编代码line 4将anon_vma的值
加8后为什么就表示了anon_vma->head的地址?
看了下面简单的例子就明白了:
struct A { int x; int y; } struct A *a = kmalloc(sizeof(struct A);设kmalloc分配出来的一块内存地址为v,
a的值就是v,
a->y的值是*(v+4),
而a指向的struct A的成员y所在的内存地址就是v+4,也即&a->y ,这就是反汇编代码line 4的来历。
另外顺便说一句,a+4的值,是&a + 4×sizeof(struct A),这些不要搞混了。
再回到开始的分析,anon_vma是个什么结构?(未完)