最近一直在关注setjmp!
发现用宏包装后的setjmp捕捉异常其实蛮native,所以简单的写了一个实现。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
#include <setjmp.h>
jmp_buf env;
pthread_t p;
#define __try__ do{if(!setjmp(env)){
#define __catch__ }else{\
#define __finally__ }}while(0);
void back(int sig){
switch(sig){
case SIGSEGV:
longjmp(env,1);
break;
case SIGFPE:
longjmp(env,1);
break;
default:
exit(-1);
}
}
void stack_protect(){
signal(SIGSEGV,&back);
signal(SIGFPE,&back);
}
void work(){
__try__;
printf("%d\n",1/0);
__catch__;
printf("1/0 was successful...\n");
__finally__;
printf("work function end...\n");
}
int main(int argc, char const *argv[]){
stack_protect();
pthread_create(&p,NULL,(void*)work,NULL);
sleep(1);
return 0;
}
可以看到,用简单的setjmp 回跳与 do...while 内嵌if..else(也可用switch...case实现多选项)的catch捕捉可以保证执行流程的同步。
优点:
由sig感知异常并恢复当前运行栈,也保证了业务面的不感知。
缺点:
需要捕捉的异常需要自己在初始化函数中定义。
注意:
此功能暂时无法运行在多线程环境下!
可以通过加工与条件、线程判断进行恢复,但这就需要根据实际业务逻辑来定制。^_^