猿问

程序仅在发布版本时崩溃-如何调试?

我这里遇到的是“薛定inger之猫”类型的问题-我的程序(实际上是我程序的测试套件,但仍然是一个程序)崩溃了,但仅在以发布模式构建时才出现,并且仅在从命令行启动时才崩溃。通过穴居人调试(即到处都是讨厌的printf()消息),我确定了代码崩溃的测试方法,尽管不幸的是,实际的崩溃似乎发生在某些析构函数中,因为我看到的最后一条跟踪消息在其他执行干净的析构函数。


当我尝试在Visual Studio中运行该程序时,它不会崩溃。从WinDbg.exe启动时也是如此。仅在从命令行启动时才发生崩溃。顺便说一句,这是在Windows Vista下发生的,不幸的是,我现在无法使用XP计算机进行测试。


如果我可以让Windows打印出堆栈跟踪信息,或者可以像终止程序一样干净地终止程序,那真是太好了。是否有人对我如何在此处获取一些更有意义的信息以及希望修复此错误有任何建议?


编辑:问题确实是由越界数组引起的,我将在本文中对此进行更多描述。感谢大家为发现此问题所提供的帮助!


慕村225694
浏览 435回答 3
3回答

拉风的咖菲猫

在我见过或听说过的100%的情况下,C或C ++程序在调试器中运行良好,但在外部运行时失败,原因一直在写到函数本地数组的末尾。(调试器将更多内容放在堆栈上,因此您不太可能覆盖重要内容。)

泛舟湖上清波郎朗

当我遇到这样的问题之前,通常是由于变量初始化。在调试模式下,变量和指针会自动初始化为零,而在发布模式下则不会。因此,如果您有这样的代码int* p;....if (p == 0) { // do stuff }在调试模式下,if中的代码未执行,但在释放模式下p中包含未定义的值,该值不太可能为0,因此执行该代码通常会导致崩溃。我会检查您的代码中是否存在未初始化的变量。这也适用于数组的内容。

胡说叔叔

到目前为止,还没有任何答案试图对可用于调试发行版应用程序的可用技术进行认真概述:由于多种原因,发行版和调试版的行为有所不同。 这是一个很好的概述。这些差异中的每一个都可能导致Release版本中的错误,而该错误在Debug版本中不存在。调试器的存在也可能会改变程序的行为,包括发行版和调试版。看到这个答案。简而言之,至少当连接到程序时,Visual Studio调试器会自动使用“调试堆”。您可以使用环境变量_NO_DEBUG_HEAP关闭调试堆。您可以在计算机属性或Visual Studio的“项目设置”中指定此设置。这可能会使崩溃与附带的调试器一起再现。有关调试堆损坏的更多信息,请参见此处。如果以前的解决方案不起作用,则需要捕获未处理的异常,并在发生崩溃的实例上附加事后调试器。您可以为此使用WinDbg,有关可用的验尸调试器及其在MSDN上的安装的详细信息您可以改进异常处理代码,如果这是生产应用程序,则应:一种。使用以下命令安装自定义终止处理程序std::set_terminate如果要在本地调试此问题,可以在终止处理程序内运行一个无限循环,并将一些文本输出到控制台以通知您std::terminate已被调用。然后连接调试器并检查调用堆栈。 或者您按照此答案中的说明打印堆栈跟踪。在生产应用程序中,您可能希望将错误报告发送回国内,最好是将其与一个小的内存转储一起发送,以便您按此处所述分析问题。b。使用Microsoft的结构化异常处理机制,该机制允许您捕获硬件和软件异常。参见MSDN。您可以使用SEH保护部分代码,并使用与a)中相同的方法来调试问题。SEH提供了有关从生产应用程序发送错误报告时可以使用的异常的更多信息。
随时随地看视频慕课网APP
我要回答