C中的abort()函数是否清理堆栈?

时间:2013-01-23 13:21:49

标签: c stack-overflow abort

例如,可以捕获SIGABRT并以longjump继续程序。

我想知道当我总是调用调用abort()的函数时,这是否会导致堆栈溢出。

我需要知道,因为我想在单元测试中使用断言宏(taht调用abort)。如果断言失败,我想继续进行下一次单元测试。

3 个答案:

答案 0 :(得分:2)

abort不需要清除堆栈; longjmp将“清除”它,因为它会将堆栈指针重新回到setjmp的位置。如果一切正确,重复调用longjmpsetjmp将不会导致堆栈溢出。

但是,longjmp将跳过正常的执行路径,这可以自行调用资源泄漏。请考虑以下代码:

char *s = malloc(...);
... use s ...
free(s);

如果“... use s ...”部分调用某些longjmp代码中的函数,free将无法被调用,您将泄漏。这同样适用于关闭打开文件,套接字,释放共享内存段,收获分叉子项等等。

因此{C}编程很少使用longjmp。如果你不想退出计划,我的建议是避免assert。只需在单元测试中使用另一个宏,或切换到提供一个宏的测试框架。

答案 1 :(得分:1)

longjmp不会展开堆栈,但会修改堆栈指针:

  

如果调用setjmp的函数返回,则不再   可以安全地使用longjmp和相应的jmp_buf对象。   这是因为当函数时堆栈帧无效   回报。 调用longjmp恢复堆栈指针,因为   返回的函数将指向一个不存在的函数   覆盖/损坏的堆栈帧。

答案 2 :(得分:1)

假设POSIX,调用longjmp退出由SIGABRT引发的abort是有效的,因为abort被指定为异步信号安全(并且还因为这个信号不是异步的)。 (在简单的C中,几乎所有来自信号处理程序的东西都是UB,所以它通常不是一个有趣的案例。)但是,你有责任确保你自己的程序都没有。#39 ; s状态因此不一致,这样会导致程序在程序流程中立即或稍后以其他方式调用UB。

话虽如此,我同意user4815162342您的提案是一种非常糟糕的错误处理形式。如果您不想中止,请不要致电abort,而是编写自己的错误处理功能。