spe*_*der 35 c++ crash debugging lua mingw
我在我的C++应用程序上遇到随机崩溃,它可能不会崩溃一个月,然后在一小时内崩溃10次,有时可能会在启动时崩溃,而有时可能会在运行几个小时后崩溃(或者不会崩溃)所有).
我在GNU/Linux上使用GCC,在Windows上使用MingW,因此我无法使用Visual Studio JIT Debug ...
我不知道如何继续,随机查看代码是行不通的,代码是巨大的(好的部分不是我的工作,它也有一些很多遗留的东西),我也没有有关如何重现崩溃的线索.
编辑:很多人提到......我如何制作核心转储,小型转储或其他转储?这是我第一次需要进行事后调试.
EDIT2:实际上,DrMingw捕获了一个调用堆栈,没有内存信息......不幸的是,调用堆栈对我没什么帮助,因为接近结束突然它进入了一些我没有调试信息的库(或其他东西) ,只产生一些十六进制数...所以我仍然需要一些体面的转储,提供更多的信息(特别是关于内存中的内容...具体来说,在那里给出了"访问冲突"错误的地方)
此外,我的应用程序使用Lua和Luabind,可能错误是由.lua脚本引起的,但我不知道如何调试它.
Mit*_*eat 29
尝试Valgrind(它是免费的,开源的):
Valgrind发行版目前包括六种生产质量工具:内存错误检测器,两个线程错误检测器,一个缓存和分支预测分析器,一个调用图生成缓存分析器和一个堆分析器.它还包括两个实验工具:堆/堆栈/全局数组溢出检测器和SimPoint基本块矢量生成器.它运行在以下平台上:X86/Linux,AMD64/Linux,PPC32/Linux,PPC64/Linux和X86/Darwin(Mac OS X).
包的Memcheck部分可能是开始的地方:
Memcheck是一个内存错误检测器.它可以检测C和C++程序中常见的以下问题.
访问内存不应该,例如超越和不足堆积块,超出堆栈顶部,并在释放后访问内存.
使用未定义的值,即尚未初始化的值,或从其他未定义值派生的值.
堆内存的释放不正确,例如双重释放堆块,或者malloc/new/new []与free/delete/delete []的使用不匹配
在memcpy和相关函数中重叠src和dst指针.
内存泄漏.
use*_*558 15
首先,您很幸运,您的进程在短时间内多次崩溃.这应该可以让你轻松进行.
这是你如何进行的.
获得崩溃转储
首先,您确实需要获得崩溃转储.
如果在崩溃时没有得到崩溃转储,那么首先编写一个产生可靠崩溃转储的测试.
使用调试符号重新编译二进制文件,或确保可以使用调试符号分析故障转储.
找到可疑的功能
鉴于您有崩溃转储,请在gdb或您最喜欢的调试器中查看它,并记住显示所有线程!它可能不是您在gdb中看到的有缺陷的线程.
看看gdb说你的二进制文件崩溃的地方,隔离一些你认为可能导致问题的函数集.
查看多个崩溃并隔离在所有崩溃中通常处于活动状态的代码部分可以节省大量时间.
收紧状态检查
通常会发生崩溃,因为某些状态不一致.最好的方法是收紧国家要求.您可以通过以下方式执行此操作
对于您认为可能导致问题的每个函数,记录输入或对象在进入函数时必须具有的合法状态.(在退出函数时必须具有相同的合法状态,但这并不重要).
如果函数包含循环,则记录在每次循环迭代开始时需要具有的合法状态.
为所有这些合法国家的表达添加断言.
重复
然后重复这个过程.如果它仍然在断言之外崩溃,则进一步收紧断言.在某些时候,进程将在一个断言上崩溃,而不是因为一些随机崩溃.此时,您可以集中精力试图找出使您的程序从进入函数的合法状态变为断言发生时的非法状态的原因.
如果将断言与详细日志记录配对,则应该更容易遵循程序的功能.
Nic*_*ght 14
如果所有其他方法都失败了(特别是如果调试器下的性能不可接受),则进行大量日志记录.从入口点开始 - 是应用程序事务吗?记录每个事务的进入.记录密钥对象的所有构造函数调用.由于崩溃是间歇性的,因此日志调用可能不会每天调用的所有函数.
你至少开始缩小,其中坠机可能是.
在调试器下启动程序(我确定调试器与GCC和MingW一起)并等到它在调试器下崩溃.在崩溃时,您将能够看到哪些特定操作失败,查看汇编代码,寄存器,内存状态 - 这通常可以帮助您找到问题的原因.
在我工作的地方,崩溃程序通常会生成一个可以在windbg中加载的核心转储文件.
然后我们在程序崩溃时有一个内存映像.没有什么可以用它来做,但至少它给你最后一个调用堆栈.一旦你知道崩溃的功能,你就可以追踪问题,至少你可以将问题减少到更可重复的测试用例.
这些类型的错误总是很棘手 - 除非您可以重现错误,否则您唯一的选择是更改您的应用程序,以便记录额外的信息,然后等到错误再次发生.
有一个名为Process Dumper的优秀工具,您可以使用它来获取遇到异常或意外退出的进程的故障转储 - 您可以要求用户安装它并为您的应用程序配置规则.
或者,如果您不想要求用户安装其他应用程序,您可以让应用程序监视异常并通过调用MiniDumpWriteDump创建转储本身.
另一个选择是改进日志记录,但是要确定要记录哪些信息(不仅记录所有内容)可能会很棘手,因此可能需要多次崩溃 - 更改日志记录以查找问题.
正如我所说,这些类型的错误总是很难诊断 - 根据我的经验,它通常需要花费数小时的时间来查看日志和崩溃转储,直到突然间你得到一切都有意义的尤里卡时刻 - 关键是收集正确的信息.
听起来你的程序正在遭受内存损坏.如前所述,你在Linux上的最佳选择可能是valgrind.但这里还有两个选择:
首先使用调试malloc.几乎所有的C库都提供了一个初始化内存的调试malloc实现(正常malloc在内存中保留"旧"内容),检查已分配块的边界是否存在损坏等等.如果这还不够,那么第三方实施的选择范围很广.
您可能想看看VMWare Workstation.我没有这样设置,但是从他们的营销材料中他们支持一种相当有趣的调试方式:在"录制"虚拟机中运行debugee.当发生内存损坏时,在损坏的地址处设置内存断点,然后将 VM中的时间转回到该内存被覆盖的那一刻.有关如何使用Linux/gdb设置重播调试的信息,请参阅此PDF.我相信Workstation 7有15或30天的演示,可能足以摆脱代码中的错误.
您已经听说过如何在 linux 下处理此问题:检查核心转储并在 valgrind 下运行您的代码。所以你的第一步可能是在 Linux 下找到错误,然后检查它们是否在 mingw 下消失。由于这里没有人提到过mudflap,我将这样做:如果您的 Linux 发行版提供了 mudflap,请使用它。mudflap 通过跟踪实际允许指针指向的信息,帮助您捕捉指针滥用和缓冲区溢出:
对于 Windows:mingw 有一个 JIT 调试器,称为 DrMingw:
| 归档时间: |
|
| 查看次数: |
25177 次 |
| 最近记录: |