Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的abort()函数是否清理堆栈?_C_Stack Overflow_Abort - Fatal编程技术网

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

C中的abort()函数是否清理堆栈?,c,stack-overflow,abort,C,Stack Overflow,Abort,例如,你可以用跳远来接住SIGABRT并继续这个项目 我想知道当我总是调用调用abort()的函数时,这是否会导致堆栈溢出 我需要知道这一点,因为我想在单元测试中使用断言宏(taht调用abort)。如果断言失败,我想继续进行下一个单元测试。不会展开堆栈,但会修改堆栈指针: 如果调用setjmp的函数返回,则它不再是 可以安全地将longjmp与相应的jmp_buf对象一起使用。 这是因为当函数 返回调用longjmp将恢复堆栈指针,这是因为 返回的函数将指向不存在且可能存在的 覆盖/损坏堆栈帧

例如,你可以用跳远来接住SIGABRT并继续这个项目

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

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

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

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


中止
不需要清除堆栈
longjmp
将“清除”它,因为它将堆栈指针倒回
setjmp
的位置。如果所有其他操作都正确,则重复调用
longjmp
setjmp
不会导致堆栈溢出

但是,
longjmp
将跳过正常的执行路径,该路径本身就可以调用资源泄漏。考虑这个代码:

char *s = malloc(...);
... use s ...
free(s);
如果“…use s…”部分调用了
longjmp
s超出代码的函数,
free
将没有机会被调用,您将泄漏。这同样适用于关闭打开的文件、套接字、释放共享内存段、获取分叉子项等


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

假设POSIX,调用
longjmp
以退出
abort
引发的
SIGABRT
是有效的,因为
abort
被指定为异步信号安全的(也因为此信号不是异步的)。(在普通的C语言中,从信号处理程序执行几乎任何操作都是非常困难的,所以这通常不是一个有趣的例子。)但是,您有责任确保自己的程序状态不会因此而不一致,以这样一种方式,它将导致您的程序立即或稍后在程序流中以其他方式调用UB


尽管如此,我同意user4815162342的观点,即您的建议是一种非常糟糕的错误处理形式。如果您不想中止,请不要调用
abort
,而是编写自己的错误处理函数。

为什么要添加标记“stackoverflow”?@govindo,因为他说的是实际的堆栈溢出!你为什么要删除它?@user4815162342哦,真的,很抱歉,他一定说了“我不知道这是否会导致堆栈溢出”,而不是“我不知道这是否会导致堆栈溢出”@govinda好吧,我想程序员知道什么是“堆栈溢出”,不需要把这句话复杂化……因为标准C没有析构函数(所有数据类型都是C++语言中的POD),展开堆栈和还原堆栈指针之间没有区别。这不是用于错误处理,只是用于单元测试,它可以按预期工作。与其他单元测试框架一样,我希望在测试函数中调用assert宏。一旦一个assert失败,此函数必须中断,下一个测试函数必须停止被调用。这正是现在发生的事情。你可以自己重新定义
断言
,但我看不出这种单元测试方法有什么可怕的错误,特别是因为你(对于某些类型的单元测试)甚至可能对
SIGSEGV
做同样的事情。。。