我正在执行我的a.out文件。执行后,程序运行一段时间,然后带着消息退出:

**** stack smashing detected ***: ./a.out terminated*
*======= Backtrace: =========*
*/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)Aborted*

可能的原因是什么?我该如何纠正?


当前回答

您可以尝试使用valgrind调试问题:

Valgrind发行版 包括六个生产质量工具: 一个内存错误检测器,两个线程 错误检测器,缓存和 分支预测分析器,a 调用图生成缓存分析器, 和一个堆分析器。它还包括 两种实验工具:a 堆/堆栈/全局数组溢出 检测器和SimPoint基本块 向量生成器。它运行在 X86/Linux、 AMD64/Linux、PPC32/Linux、PPC64/Linux、 X86/Darwin (Mac OS X)。

其他回答

这意味着您以非法的方式写入堆栈上的某些变量,很可能是缓冲区溢出的结果。

另一个堆栈破坏的来源是(不正确)使用vfork()而不是fork()。

我刚刚调试了一个这种情况,其中子进程无法执行()目标可执行文件,并返回一个错误代码,而不是调用_exit()。

因为vfork()已经生成了那个子进程,所以它返回时实际上仍然在父进程空间中执行,这不仅破坏了父进程的堆栈,而且导致“下游”代码打印了两组不同的诊断。

将vfork()更改为fork()修复了这两个问题,将子函数的return语句改为_exit()也解决了这两个问题。

但是由于子代码在execve()调用之前调用了其他例程(在本例中设置uid/gid),因此从技术上讲,它不满足vfork()的要求,因此将其更改为使用fork()在这里是正确的。

(请注意,有问题的return语句实际上并不是这样编码的——相反,调用了一个宏,该宏根据一个全局变量决定是_exit()还是返回。因此,子代码不符合vfork()的用法并不是很明显。

有关更多信息,请参见:

fork(), vfork(), exec()和clone()的区别

我在编辑该结构时遇到了这个问题,但没有重新编译使用该结构的库。在一些大项目中,我添加了新的字段到struct,后来从json在lib_struct中解析,这个库后来在小部件中使用,以显示被解析的内容。我的make文件没有覆盖依赖项,所以库在编辑结构后没有重新编译。我的解决方案是重新编译所有使用该结构的东西。

我得到了这个错误,而使用malloc()分配一些内存到一个结构*后,花了一些这个调试代码,我最终使用free()函数来释放分配的内存,随后错误消息消失了:)

堆栈损坏通常是由缓冲区溢出引起的。 你可以通过防御性的编程来防御它们。

无论何时访问数组,都要在数组前面加上断言,以确保访问没有越界。例如:

assert(i + 1 < N);
assert(i < N);
a[i + 1] = a[i];

这使您考虑数组边界,并使您考虑在可能的情况下添加测试来触发它们。如果其中一些断言在正常使用期间失败,则将它们转换为常规If。