简体   繁体   English

需要有关缓冲区溢出的帮助

[英]Need help with buffer overrun

I've got a buffer overrun I absolutely can't see to figure out (in C). 我有一个缓冲区溢出我绝对看不出来(在C中)。 First of all, it only happens maybe 10% of the time or so. 首先,它只发生在10%的时间左右。 The data that it is pulling from the DB each time doesn't seem to be all that much different between executions... at least not different enough for me to find any discernible pattern as to when it happens. 它每次从数据库中提取的数据在执行之间似乎并没有那么大的差别......至少在不同的情况下我找不到任何可辨别的模式。 The exact message from Visual Studio is this: 来自Visual Studio的确切消息是:

A buffer overrun has occurred in hub.exe which has corrupted the program's internal state. hub.exe中发生缓冲区溢出,损坏了程序的内部状态。 Press Break to debug the program or Continue to terminate the program. 按Break可调试程序或继续终止程序。

For more details please see Help topic 'How to debug Buffer Overrun Issues'. 有关更多详细信息,请参阅帮助主题“如何调试缓冲区溢出问题”。

If I debug, I find that it is broken in __report_gsfailure() which I'm pretty sure is from the /GS flag on the compiler and also signifies that this is an overrun on the stack rather than the heap. 如果我调试,我发现它在__report_gsfailure()被破坏,我很确定它来自编译器上的/ GS标志,并且还表示这是堆栈上的溢出而不是堆。 I can also see the function it threw this on as it was leaving, but I can't see anything in there that would cause this behavior, the function has also existed for a long time (10+ years, albeit with some minor modifications) and as far as I know, this has never happened. 我也可以看到它在离开时抛出的功能,但我看不到会导致这种行为的任何东西,该功能也存在了很长时间(10年以上,虽然有一些小修改)据我所知,这从未发生过。

I'd post the code of the function, but it's decently long and references a lot of proprietary functions/variables/etc. 我发布了函数的代码,但是它很长并且引用了许多专有函数/变量/等。

I'm basically just looking for either some idea of what I should be looking for that I haven't or perhaps some tools that may help. 我基本上只是想找一些我应该寻找的东西,我没有或者可能有些工具可能有所帮助。 Unfortunately, nearly every tool I've found only helps with debugging overruns on the heap, and unless I'm mistaken, this is on the stack. 不幸的是,我发现的几乎所有工具只能帮助调试堆上的溢出,除非我弄错了,否则它就在堆栈中。 Thanks in advance. 提前致谢。

You could try putting some local variables on either end of the buffer, or even sentinels into the (slightly expanded) buffer itself, and trigger a breakpoint if those values aren't what you think they should be. 您可以尝试在缓冲区的任一端放置一些局部变量,或者甚至将标记放入(略微扩展的)缓冲区本身,如果这些值不是您认为的那样,则触发断点。 Obviously, using a pattern that is not likely in the data would be a good idea. 显然,使用数据中不太可能的模式是个好主意。

While it won't help you in Windows, Valgrind is by far the best tool for detecting bad memory behavior. 虽然它在Windows中无法帮助您,但Valgrind是迄今为止检测不良内存行为的最佳工具。

If you are debugging the stack, your need to get to low level tools - place a canary in the stack frame (perhaps a buffer filled with something like 0xA5) around any potential suspects. 如果你正在调试堆栈,你需要使用低级工具 - 在任何潜在的嫌疑人周围放置一个金丝雀在堆栈框架中(可能是一个填充了类似0xA5的缓冲区)。 Run the program in a debugger and see which canaries are no longer the right size and contain the right contents. 在调试器中运行该程序,查看哪些canaries不再是正确的大小并包含正确的内容。 You will gobble up a large chunk of stack doing this, but it may help you spot exactly what is occurring. 你会吞噬大量的堆栈,但它可以帮助你准确发现正在发生的事情。

One thing I have done in the past to help narrow down a mystery bug like this was to create a variable with global visibility named checkpoint . 我过去做过的一件事就是帮助缩小这样一个神秘的bug,就是创建一个名为checkpoint全局可见性变量。 Inside the culprit function, I set checkpoint = 0; 在罪魁祸首功能里面,我设置了checkpoint = 0; as the very first line. 作为第一线。 Then, I added ++checkpoint; 然后,我添加了++checkpoint; statements before and after function calls or memory operations that I even remotely suspected might be able to cause an out-of-bounds memory reference (plus peppering the rest of the code so that I had a checkpoint at least every 10 lines or so). 我甚至远程怀疑的函数调用或内存操作之前和之后的语句可能会导致超出范围的内存引用(加上代码的其余部分,以便我至少每10行左右有一个检查点)。 When your program crashes, the value of checkpoint will narrow down the range you need to focus on to a handful of lines of code. 当程序崩溃时, checkpoint的值将缩小您需要关注的范围到一些代码行的范围。 This may be a bit overkill, I do this sort of thing on embedded systems (where tools like valgrind can't be used) but it should still be useful. 这可能有点矫枉过正,我在嵌入式系统上做这种事情(不能使用像valgrind这样的工具),但它应该仍然有用。

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

Does this program recurse at all? 这个程序是否完全递归? If so, I check there to ensure you don't have an infinite recursion bug. 如果是这样,我检查那里以确保你没有无限的递归错误。 If you can't see it manually, sometimes you can catch it in the debugger by pausing frequently and observing the stack. 如果您无法手动查看,有时您可以通过暂停并观察堆栈来在调试器中捕获它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM