可以使用信号处理程序加setjmp
/来完成longjmp
。
我不确定这个解决方案有多可靠。当我测试它时它可以工作,但可能包含未定义的行为,所以不要依赖它。
同样重要的是要注意,有缺陷的代码可以做比分段错误更糟糕的事情。例如,它可能会损坏内存,因此您的测试代码或其他测试代码将失败。
下面的代码主要基于这个答案。
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
static void good_func(void)
{
int q, *p = &q;
printf("%s running\n", __FUNCTION__);
*p = 3;
}
static void bad_func(void)
{
int *p = NULL;
printf("%s running\n", __FUNCTION__);
*p = 3;
}
static jmp_buf context;
static void sig_handler(int signo)
{
longjmp(context, 1);
}
static void catch_segv(int catch)
{
struct sigaction sa;
if (catch) {
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = sig_handler;
sa.sa_flags = SA_RESTART;
sigaction(SIGSEGV, &sa, NULL);
} else {
sigemptyset(&sa);
sigaddset(&sa, SIGSEGV);
sigprocmask(SIG_UNBLOCK, &sa, NULL);
}
}
typedef void (*func_t)(void);
static int safe_run(func_t func)
{
catch_segv(1);
if (setjmp(context)) {
catch_segv(0);
return 0;
}
func();
catch_segv(0);
return 1;
}
int main()
{
printf("good_func is %s\n", safe_run(good_func) ? "good" : "bad");
printf("bad_func is %s\n", safe_run(bad_func) ? "good" : "bad");
return 0;
}