我正在用 C 语言开发一个涉及链表的项目,我需要对一段代码进行段错误以证明它不起作用。但我的代码不会崩溃。
到目前为止,这是我的处理程序:
typedef void sigfunc(int);
sigfunc *signal(int, sigfunc*);
void Handler(int sig)
{
if (sig == SIGSEGV)
printf("received SegFault\n");
signal(SIGSEGV, &Handler);
}
它需要在段错误中存活下来。到目前为止,我得到的只是“收到的段错误”的无限循环。提前致谢!
一般来说,一旦遇到 SEGFAULT,您的流程就完成了。
在专业术语中,恢复可能是可能的,但在没有敏锐地意识到自己在做什么的情况下这样做会导致重复失败、内存泄漏、无效指针和其他问题的噩梦。
也就是说,除非您可以重新启动您的进程(这避免了上述所有情况),否则您可以尝试使用 setjmp()
和 longjmp()
进行恢复。例如:
#include <setjmp.h>
jmp_buf restore_point;
void Handler(int sig)
{
if (sig == SIGSEGV)
{
printf("received SegFault\n");
signal(SIGSEGV, &Handler);
longjmp(restore_point, SIGSEGV);
}
}
void test()
{
int fault_code = setjmp(restore_point);
if (fault_code == 0)
{
// do something that might cause a segfault
}
else
{
printf("recovered from a fault; code = %d\n", fault_code);
}
}
除了我列出的其他问题外,还有一个就是你设置的还原点(跳转缓冲区)只有在调用setjmp()
的作用域终止时才有效....你必须不跳回终止的范围!
本质上,longjmp()
是一个影响深远的 goto
,但更像是一个 gobackto
,因为它返回到跳跃缓冲区已初始化。它由 setjmp()
函数初始化,确保 setjmp()
在被线性调用时返回 0,而在被调用时返回非零值被 longjmp 进入。在那种情况下,它返回任何 longjmp()
的第二个参数(除非那个参数 == 0,在这种情况下它仍然返回非零值)。
说真的,我已经给了你足够的信息让你变得危险,但不要轻视我的警告......用这种方法使你的问题复杂化比解决它们要容易得多,除非你已经采取非常小心并限制您使用此工具。