BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / embedded-system / #591同步于 2008/6/10
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Embedded_System机器人发帖

[合集] 【原创】从segment fault得到更多信息

Winters101
2008/6/10镜像同步0 回复
☆─────────────────────────────────────☆ DusTin (老了) 于 (Mon Jun 2 20:50:41 2008) 提到: 在我刚刚开始接触linux编程的时候认为segment fault简直就是灾难。。。为了检查错误原因要一步步排查,费时费力 其实在产生segment fault的时候,kernel把能提供给我们的信息都提供给我们了,而我们所要做的就是得到这些信息。 如果能在产生segment fault的时候得到寄存器的值,特别是PC的值就可以马上利用objdump反汇编锁定错误代码,为bug fix提供了方便。其实在产生错误的时候,kernel已经把寄存器的值保存好了,并留好接口让你去拿,拿不拿就看你了,呵呵 产生segment fault的时候,会产生一个SIGSEGV信号,我们所要做的就是在应用程序捕捉这个信号。 struct sigaction s; s.sa_flags = SA_SIGINFO; s.sa_sigaction = (void *) myhandler; if (sigaction(SIGSEGV, &s, (struct sigaction *) NULL)) { printf("Sigaction returned error = %d\n", errno); exit(0); } 当捕获到这个信号之后就回去调用myhandler这个程序 static void myhandler(unsigned int sn, siginfo_t * si, struct ucontext *sc) 我们希望得到的信息就存放在这几个参数里面 sn为捕获的信号既SIGSEGV 以arm为例看一下后两个参数 typedef struct siginfo { int si_signo; int si_errno; int si_code; union { int _pad[SI_PAD_SIZE]; /* kill() */ struct { pid_t _pid; /* sender's pid */ uid_t _uid; /* sender's uid */ } _kill; /* POSIX.1b timers */ struct { unsigned int _timer1; unsigned int _timer2; } _timer; /* POSIX.1b signals */ struct { pid_t _pid; /* sender's pid */ uid_t _uid; /* sender's uid */ sigval_t _sigval; } _rt; /* SIGCHLD */ struct { pid_t _pid; /* which child */ uid_t _uid; /* sender's uid */ int _status; /* exit code */ clock_t _utime; clock_t _stime; } _sigchld; /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ struct { void *_addr; /* faulting insn/memory ref. */ } _sigfault; /* SIGPOLL */ struct { int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ int _fd; } _sigpoll; } _sifields; } siginfo_t; struct sigcontext { unsigned long trap_no; unsigned long error_code; unsigned long oldmask; unsigned long arm_r0; unsigned long arm_r1; unsigned long arm_r2; unsigned long arm_r3; unsigned long arm_r4; unsigned long arm_r5; unsigned long arm_r6; unsigned long arm_r7; unsigned long arm_r8; unsigned long arm_r9; unsigned long arm_r10; unsigned long arm_fp; unsigned long arm_ip; unsigned long arm_sp; unsigned long arm_lr; unsigned long arm_pc; unsigned long arm_cpsr; unsigned long fault_address; }; 我就不分析这两个结构了,我们想要的东西都在里面了 自己去取吧 呵呵 ☆─────────────────────────────────────☆ sunflour (Adam) 于 (Tue Jun 3 16:30:36 2008) 提到: +精阿 ☆─────────────────────────────────────☆ guying (宙斯) 于 (Tue Jun 3 20:09:44 2008) 提到: 不错 ☆─────────────────────────────────────☆ wangzai (旺仔) 于 (Wed Jun 4 21:25:55 2008) 提到: 现在还没接触到linux,不过也保存先了哈! ☆─────────────────────────────────────☆ lester98 (奶瓶) 于 (Thu Jun 5 12:23:16 2008) 提到: lz搞地很底层啊,连寄存器的值都看 ☆─────────────────────────────────────☆ sunflour (Adam) 于 (Fri Jun 6 09:19:51 2008) 提到: 用底层的办法解决上层的问题 ☆─────────────────────────────────────☆ sunflour (Adam) 于 (Fri Jun 6 13:09:57 2008) 提到: 申请转载到个人blog上可以吗 ☆─────────────────────────────────────☆ DusTin (老了) 于 (Fri Jun 6 13:51:06 2008) 提到: ^_^ 【 在 sunflour 的大作中提到: 】 : 申请转载到个人blog上可以吗
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。