调试难以找到的异常
Debugging hard-to-find exceptions
首先,感谢您花时间查看我的问题并提供帮助。我注意到这里的很多提问者几乎没有表示赞赏,但我真诚地感谢这里的帮助和社区:)
我为一个没有源代码的应用程序(这是一个视频游戏)写了一个C++插件(泄露了数百个源文件)。换句话说,我只有插件的源代码,但没有游戏。现在,在我的插件中的数千行中,有什么东西导致游戏引擎抛出(可能是访问违规),我不知道在哪里。调试器中断时,堆栈已损坏,我得到的只是没有源的DLL的十六进制地址(但异常肯定发生在我的DLL中)。我什么都试过了。。。我似乎就是找不到异常发生的地方。有时调试器指向一个"内存重定位"函数(我从未在插件中使用过),有时它指向引擎的GameFrame(),有时则指向损坏回调(所有这些都是类的不同成员函数)。
我几乎什么都试过了。。。我在谷歌上搜索了几个小时,试图找出如何使用其他调试器,如WinDbg和Microsoft应用程序验证程序。我试图注释掉调试器指向的一个或另一个,或两者,但它仍然崩溃。我甚至将OUTPUT("The name of the last executed function is: %s", __FUNCTION__)
插入到我的应用程序中的每个函数中,希望能费力地捕获最后一个函数,但似乎任何类型的I/O都会出于某种原因阻止异常的发生。。。经过10分钟的调试,崩溃发生在最后一个随机执行的函数上。
我找不到这种访问违规发生在哪里,也找不到一些临时对象在哪里被删除以导致这些坏指针(我在使用它之前会检查每个指针),但该死的,我已经达到了极限。
那么,如何调试不可能的。。。一个糟糕的调试器调用堆栈随机崩溃?提前感谢您的耐心和善意帮助!
我的建议:尝试不同的调试器(非MS),它们会捕获不同的东西。我的经验:我有一个程序的源代码和完整的调试符号破坏了堆栈,VS和WinDbg都可以帮助,但Ollydbg用值"r for pattern."注释了一个非字符串var,所以我已经在这个var上覆盖了一些字符串缓冲区。此外,Ollydbg可以选择艰难地遍历堆栈(不使用dbghelp.dll)
根据我的经验,"预防胜于治疗"这句古老的格言非常贴切。最好是通过遵循良好的软件开发实践(单元测试、回归、代码审查等)来防止错误悄悄出现,而不是在错误出现后再解决。
当然,现实世界并不是完美的,bug确实会出现。要调试内存损坏,你有一些不错的工具,比如valgrind,它至少缩小了问题的范围,让你仔细研究一下。调试一个复杂的程序并不容易,如果你的调试器出现问题,你需要大量的持久性。我发现一种有用的技术是选择性地启用或禁用某些模块,以缩小模块存在问题的范围。
有时您需要使用"引用透明度"来卸载一些模块。举个简单的例子,考虑一下:
int foo = factorial(3);
如果我怀疑这段代码中有问题(在我看到调用堆栈之前调试器就崩溃了),我必须尝试删除这段代码,看看问题是否仍然存在。但是foo
可能会在以后使用,所以我不能直接删除它。相反,我可以用int foo = 6;
替换它并继续。
另一个重要的点是始终维护一个跟踪文件,您的代码会在其中记录它正在做的事情。当程序崩溃时,跟踪文件通常可以帮助缩小问题范围。当然,默认情况下会禁用跟踪,这样就不会造成性能瓶颈。
- 在调试模式下引发C++ "deque iterator not dereferencable"异常
- 为什么调试器引发"read access violation. this was nullptr"异常?
- 添加新行时工作代码引发异常.调试技巧?
- SIGABRT 和线程相关的异常,但在调试期间工作正常
- Android ARM C++异常调试
- Visual Studio图形调试器引发读取访问冲突异常
- 在类声明中初始化 const 成员变量时在调试模式下出现异常
- 调试"在抛出 ..) 实例后终止调用",当异常 _should_ 被捕获时
- basic_string::替换的超出范围异常,而在范围内,正如调试相同参数的输出所证明的那样
- 调试器在异常C++时未挂起调试对象
- 捕获块调试语句在引发异常后未执行
- 调试器在 nullptr 检查期间引发 nullptr 异常
- QT创建者和MSVC-忽略调试时特定的异常类型
- Qt:如何在QByteArray中调试错误的分配异常
- C 调试中断异常
- 调试难以找到的异常
- 在Visual Studio 2010 c ++中调试时出现奇怪的异常
- 在Visual Studio C 调试模式中捕获异常的最佳方法仅在从IDE运行时才会发生
- 如何调试C++非托管代码中的较低级别文件访问异常/崩溃
- 未捕获的异常调试技术(C++)