4

我有一个缓冲区溢出,我绝对看不到(在 C 中)。首先,它只发生在大约 10% 的时间里。它每次从数据库中提取的数据在执行之间似乎并没有太大的不同……至少差异不足以让我找到任何可辨别的模式来确定它何时发生。来自 Visual Studio 的确切消息是这样的:

hub.exe 中发生缓冲区溢出,损坏了程序的内部状态。按 Break 调试程序或按 Continue 终止程序。

有关详细信息,请参阅帮助主题“如何调试缓冲区溢出问题”。

如果我调试,我发现它被破坏了__report_gsfailure(),我很确定这是来自编译器上的 /GS 标志,并且还表示这是堆栈而不是堆上的溢出。我还可以看到它在离开时抛出的功能,但我看不到任何会导致这种行为的东西,该功能也已经存在了很长时间(10 多年,尽管有一些小的修改)据我所知,这从未发生过。

我会发布函数的代码,但它相当长并且引用了许多专有函数/变量/等。

我基本上只是在寻找一些关于我应该寻找的我没有的想法,或者一些可能有帮助的工具。不幸的是,我发现的几乎所有工具都只能帮助调试堆上的溢出,除非我弄错了,否则它在堆栈上。提前致谢。

4

5 回答 5

3

虽然它在 Windows 中对您没有帮助,但Valgrind是迄今为止检测不良内存行为的最佳工具。

如果您正在调试堆栈,则需要使用低级工具 - 在堆栈帧中放置一个金丝雀(可能是一个填充有 0xA5 之类的缓冲区)围绕任何潜在的嫌疑人。在调试器中运行程序,看看哪些金丝雀不再是正确的大小并且包含正确的内容。这样做你会吞噬一大块堆栈,但它可以帮助你准确地发现正在发生的事情。

于 2010-04-30T18:45:19.107 回答
3

您可以尝试将一些局部变量放在缓冲区的任一端,甚至将哨兵放入(稍微扩展的)缓冲区本身,如果这些值不是您认为的值,则触发断点。显然,使用数据中不太可能出现的模式将是一个好主意。

于 2010-04-30T18:52:57.613 回答
1

我过去为帮助缩小像这样的神秘错误所做的一件事是创建一个具有全局可见性的变量,名为checkpoint. 在罪魁祸首函数中,我设置checkpoint = 0;为第一行。然后,我++checkpoint;在函数调用或内存操作之前和之后添加了语句,我什至怀疑这些语句可能会导致越界内存引用(加上对其余代码的添加,以便我至少每 10 行就有一个检查点或者)。当您的程序崩溃时, 的值checkpoint会将您需要关注的范围缩小到几行代码。这可能有点矫枉过正,我在嵌入式系统上做这种事情(valgrind不能使用像这样的工具),但它应该仍然有用。

于 2010-04-30T20:47:28.643 回答
0

将其包装在异常处理程序中,并在发生时转储有用信息。

于 2010-04-30T18:47:06.877 回答
0

这个程序会递归吗?如果是这样,我会在那里检查以确保您没有无限递归错误。如果你不能手动看到它,有时你可以通过经常暂停并观察堆栈来在调试器中捕获它。

于 2010-04-30T20:28:37.887 回答