我经历过某些错误可能会导致程序在作为常规构建执行时崩溃,但在调试器中执行时会被抑制。我最近在一个Qt项目中遇到过这种情况,其中99%会导致崩溃的错误是由解除引用空指针引起的分段错误。
在Linux上我用valgrind跟踪那些。现在我体验到我的项目在没有崩溃的情况下在linux上构建良好,但是在Windows上的Qt创建者的构建将在某个操作时崩溃。使用调试器时,它不会。我和valgrind经历了同样的事情。
什么可能导致此行为?如何在调试器和valgrind将其抑制时跟踪崩溃的原因?
Linux上的编译器是g ++ 4.4.7,而在windows上它是mingw492_32。
答案 0 :(得分:1)
我不知道在Windows调试中有任何明确的异常抑制。您可以在public class ValidationError : BaseValidator
{
private ValidationError(string message)
: base()
{
ErrorMessage = message;
IsValid = false;
}
protected override bool EvaluateIsValid()
{
return false;
}
public static void DisplayError(string message, string validationGroup)
{
var currentPage = HttpContext.Current.Handler as Page;
currentPage.Validators.Add(new ValidationError(message) { ValidationGroup = validationGroup });
}
}
下设置哪些例外触发程序中断,但我认为这不是您所要求的。
我发现从调试器运行Windows程序时无法重现的问题,我的意思是Visual Studio 20xx。我相信这是因为IDE设置了不同的Win32和CRT堆内存管理标志。可能在调试器中运行也会巧妙地改变时序(你有一个Heisenbug)。无论我运行Debug构建还是Release构建,都是如此。在这些情况下,我的第一步是“正常”启动程序,可能使用Debug Menu->Exceptions
或类似的启动延迟。然后将调试器附加到已启动的进程,而人工延迟则为您提供时间。
这似乎保留了程序的操作特性,使得从调试器运行它不会。我发现可能不止一次重现奇怪的崩溃。
如果它仍然无法重现崩溃,您将不得不变得更有创意:添加仪器;使用Process Dumper在崩溃时强制执行内存转储,然后调试dump post mortem 。
希望我提到的第一步是有效的,因为如果不这样做会越来越痛苦。
答案 1 :(得分:1)
调试器通常可以掩盖的一种类型的错误是竞争条件'。 由于调试器通常会更改线程运行/调度之间的时间,因此在调试器下运行程序可能会导致竞争条件永远(或有时总是)被触发。
答案 2 :(得分:0)
通常会出现这种差异,因为在调试模式下,您只是不会落后于内存屏障,因为它的布局不同,但不是因为调试器以某种方式抑制了问题。如果您在任何模式和任何平台上崩溃,您应该修复该错误。否则你会在你的程序中随机事件中断你的腿。
此外,发布崩溃的原因之一可能是程序优化。它还会更改内存布局并导致更多崩溃。要跟踪这些问题,您可以尝试启用优化,但保持调试信息能够跟踪。