在运行Linux内核3.0.35的ARM Cortex-A9(飞思卡尔iMX6SL)上,我看到一个内核oops,PC和LR(0x402aca32 / 0x402ac3cd)位于用户空间。模式是USER_32,ISA是Thumb。此系统上没有以Thumb模式执行的代码。
[ 597.195954] Unable to handle kernel paging request at virtual address 000a34d4
[ 597.205436] pgd = c35dc000
[ 597.208149] [000a34d4] *pgd=8c454831, *pte=8374c1cf, *ppte=8374ca3e
[ 597.214657] Internal error: Oops: 81f [#1] PREEMPT
[ 597.219609] Modules linked in: ...<snip>...
[ 597.243075] CPU: 0 Tainted: P W (3.0.35-aaaaaa #1)
[ 597.249162] PC is at 0x402aca32
[ 597.252304] LR is at 0x402ac3cd
[ 597.255448] pc : [<402aca32>] lr : [<402ac3cd>] psr: 60000030
[ 597.255453] sp : be8fc220 ip : 00000000 fp : 00000809
[ 597.266940] r10: 00000004 r9 : 40336ea0 r8 : 00000818
[ 597.272168] r7 : 4034c25c r6 : 00011b31 r5 : 00001250 r4 : 000a2cc8
[ 597.278698] r3 : 00000000 r2 : 000a34d0 r1 : 00011b30 r0 : 00000809
[ 597.285229] Flags: nZCv IRQs on FIQs on Mode USER_32 ISA Thumb Segment user
[ 597.292629] Control: 10c53c7d Table: 835dc059 DAC: 00000015
[ 597.298378] Process wancontrol (pid: 7551, stack limit = 0xce9f02e8)
[ 597.307890] ---[ end trace f50414d2a3d239df ]---
[ 597.312516] Kernel panic - not syncing: Fatal exception in interrupt
[ 597.325257] Backtrace:
[ 597.327567] [<c0135248>] (dump_backtrace+0x0/0x110) from [<c041e188>] (dump_stack+0x18/0x1c)
[ 597.336837] r6:c3088d20 r5:ce9f02e8 r4:c0537b48 r3:00000002
[ 597.342382] [<c041e170>] (dump_stack+0x0/0x1c) from [<c041e200>] (panic+0x74/0x194)
[ 597.350794] [<c041e18c>] (panic+0x0/0x194) from [<c01355b0>] (die+0x1a4/0x1e4)
[ 597.358402] r3:07ffff00 r2:ce9f1db8 r1:c0537f90 r0:c04ac8ba
[ 597.364044] r7:00000000
[ 597.366591] [<c013540c>] (die+0x0/0x1e4) from [<c013a7b0>] (__do_kernel_fault+0x6c/0x8c)
[ 597.375465] r8:00000000 r7:ce9f1fb0 r6:cee35900 r5:0000081f r4:000a34d4
[ 597.382060] [<c013a744>] (__do_kernel_fault+0x0/0x8c) from [<c013aa90>] (do_page_fault+0x2c0/0x2f0)
[ 597.391760] r8:cee35900 r7:000a34d4 r6:c3088d20 r5:ce9f1fb0 r4:00000001
[ 597.398438] r3:ce9f1fb0
[ 597.400909] [<c013a7d0>] (do_page_fault+0x0/0x2f0) from [<c012c1b8>] (do_DataAbort+0x38/0xa0)
[ 597.410178] [<c012c180>] (do_DataAbort+0x0/0xa0) from [<c0131a88>] (ret_from_exception+0x0/0x10)
[ 597.419298] Exception stack(0xce9f1fb0 to 0xce9f1ff8)
[ 597.424664] 1fa0: 00000809 00011b30 000a34d0 00000000
[ 597.434300] 1fc0: 000a2cc8 00001250 00011b31 4034c25c 00000818 40336ea0 00000004 00000809
[ 597.442488] 1fe0: 00000000 be8fc220 402ac3cd 402aca32 60000030 ffffffff
[ 597.455455] r8:00000818 r7:4034c25c r6:00011b31 r5:0000000f r4:0000040f
如果代码在用户空间中执行,则应该获得SEGV。
void arm_notify_die(const char *str, struct pt_regs *regs,
struct siginfo *info, unsigned long err, unsigned long trap)
{
if (user_mode(regs)) {
current->thread.error_code = err;
current->thread.trap_no = trap;
force_sig_info(info->si_signo, info, current);
} else {
die(str, regs, err);
}
}
为什么会进入死亡()?
对于相同的地址0x000a34d4,使用相同的回溯重复发生这种情况。我不能说堆栈已被清除,因为在这个内核的不同实例中值看起来相同。