这是由solit在群里面的一个问题引起的:
当一个进程里的一个线程遇到异常的时候,该异常的影响范围有多大?
例如一个进程有四个线程,其中一个线程出现了除以0的操作,最后会怎样?
首先,应该明确一个事情:发生除零的时候,CPU会发生异常。
王耀(349705337) 21:53:12
这些OS都有默认的异常处理函数
这个结果是受测试程序的影响的
如果代码进行了异常处理
王耀(349705337) 22:04:46
try catch了
王耀(349705337) 22:05:17
注册了SIGFPE信号处理函数
王耀(349705337) 22:16:29
/*
1122 * Take down every thread in the group. This is called by fatal signals
1123 * as well as by sys_exit_group (below).
1124 */
王耀(349705337) 22:16:58
follow了一下内核代码,找到了这个函数
王耀(349705337) 22:17:44
实际上,你可以直接向一个多线程程序发送SIGFPE信号也可以达到相同的效果
王耀(349705337) 22:18:07
如果用户空间没有指定信号处理函数
王耀(349705337) 22:18:17
就会调用内核默认的信号处理函数
王耀(349705337) 22:18:21
do_signal
王耀(349705337) 22:19:39
另外,还可以做一个有意思的测试
王耀(349705337) 22:19:58
来理解异常和中断的区别
王耀(349705337) 22:21:35
#include
#include
static void sig_fpe(int sig)
{
printf("div zero.\n");
}
int main()
{
signal(SIGFPE,sig_fpe);
int a = 40/0;
return 0;
}
王耀(349705337) 22:21:48
看出现什么效果:-)
王耀(349705337) 22:25:58
可以想想这是怎么回事?怎么会不停的接受到SIGFPE信号呢
王耀(349705337) 22:26:08
为什么会出现这种情况呢
原因:
其实发生异常时,CPU(x86)会将当前 EIP (指向引发异常的指令)压栈,
发生中断时,CPU将当前 EIP 的“后”一个地址(指向引发中断的指令的后一条指令)压栈。
在异常处理代码中,如果认为能够从灾难中恢复,可以不修改被压栈的EIP,从而返回到引发异常的指令处。
参考:
http://blog.chinaunix.net/u/14165/showart_81011.html
阅读(326) | 评论(0) | 转发(0) |