arch/arm/mm/fault.c
__do_user_fault(struct task_struct *tsk, unsigned long addr,
unsigned int fsr, unsigned int sig, int code,
struct pt_regs *regs)
{
struct siginfo si;
#ifdef CONFIG_DEBUG_USER // 1. 配置内核
if (user_debug & UDBG_SEGV) {
printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
tsk->comm, sig, addr, fsr);
show_pte(tsk->mm, addr);
show_regs(regs);
}
#endif
2. uboot: set bootargs user_debug=0xff
执行应用程序会报错,并打印堆栈,反汇编应用程序查看出错信息
---------------------打印堆栈的信息---------------
# ./test
a = 0x12
pgd = c3d64000
[00000000] *pgd=30724031, *pte=00000000, *ppte=00000000
Pid: 773, comm: test
CPU: 0 Not tainted (2.6.22.6 #11)
PC is at 0x84ac
LR is at 0x84d0
pc : [<000084ac>] lr : [<000084d0>] psr: 60000010
sp : be80ee30 ip : be80ee44 fp : be80ee40
r10: 4013365c r9 : 00000000 r8 : 00008514
r7 : 00000001 r6 : 000085cc r5 : 00008568 r4 : be80eeb4
r3 : 00000012 r2 : 00000000 r1 : 00001000 r0 : 00000000
Flags: nZCv IRQs on FIQs on Mode USER_32 Segment user
Control: c000717f Table: 33d64000 DAC: 00000015
[<c002cd1c>] (show_regs+0x0/0x4c) from [<c0031a98>] (__do_user_fault+0x5c/0xa4)
r4:c04a8080
[<c0031a3c>] (__do_user_fault+0x0/0xa4) from [<c0031d38>] (do_page_fault+0x1dc/0x20c)
r7:c00271e0 r6:c3d26278 r5:c04a8080 r4:ffffffec
[<c0031b5c>] (do_page_fault+0x0/0x20c) from [<c002b224>] (do_DataAbort+0x3c/0xa0)
[<c002b1e8>] (do_DataAbort+0x0/0xa0) from [<c002be48>] (ret_from_exception+0x0/0x10)
Exception stack(0xc3efbfb0 to 0xc3efbff8)
bfa0: 00000000 00001000 00000000 00000012
bfc0: be80eeb4 00008568 000085cc 00000001 00008514 00000000 4013365c be80ee40
bfe0: be80ee44 be80ee30 000084d0 000084ac 60000010 ffffffff
r8:00008514 r7:00000001 r6:000085cc r5:00008568 r4:c039bfc8
Segmentation fault
-------------------------------------------------------
但是这个堆栈并没有打印出来用户空间的程序的栈,打印的是内核的,需要自己修改内核打印堆栈,然后再反汇编相应的应用程序,根据pc值进行偏移判断出错的位置
main函数是谁调用的.动态库调用,怎么知道他的地址
1.cat相应进程目录下有个maps文件
2.gdbserver运行测试程序,ubuntu上运行gdb
(gdb) info file
动态链接不好确认地址,静态的比较好确认
编译的时候加上-static就是静态链接
1.配置内核开始CONFIG_DEBUG_USER
2.u_boot中需要传入user_debug
3.修改fault.c中函数__do_user_fault(struct task_struct *tsk, unsigned long addr,打印其堆栈里面的信息
bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0 user_debug=0xff