ARM定义了有七种异常,当有异常发生时,ARM会根据异常的类型自动执行异常向量表中的指令。
这几种异常具体如下:
reset SVC +0x00
undefine UND +0x04
SWI SVC +0x08
prefetch ABT +0x0c
data abort ABT +0x10
IRQ IRQ +0x18
FIQ FIQ +0x1c
以下简单说说在编程中本人常见的几种异常:
1. 除零异常,
当被除数为零时,就会发生除零异常;
此时kernel会发出Signal 8(SIGFPE)
2. un-align data abort,
未对齐的数据访问导致的data abort。
例如,
int* pi_test = (int *)0x44332211;
*pi_test = 0;
这时系统就会产生un-align data abort。
因为现代的编译器已经越来越智能,编译时能够给指针一个对齐的地址,
所以这种异常并不是很常见;
3. data abort
这是编程中及其常见的一类abort,
比如空指针的读写、写rodata section等等都会发出这种abort。
此时kernel会发出Signal 11(SIGSEGV)Segmentation fault出来。
4. prefetch abort
ARM CPU根据一个地址预取指令,发现地址取不出数据或无法访问时,
就会触发预取指令异常。
typedef void (*pf_abort)(void);
pf_abort pf_abort_func = 0x44556678;
/* call pf_abort_func */
pf_abort_func();
运行程序就会abort了。
幸运的是,以上介绍的几种abort大部分情况下都能通过系统产生的core文件来debug出问题点。
PC+LR+linux tools(readelf/nm/objdump)来查到地址对应的符号。
abort是常见的一类变成错误,作为程序员应该要以平常心对待之。
另外从另一个角度来讲,多使用ASSERT+error handling可以帮助你写出更健壮的程序。