Debugging JIT调试在C#应用程序中隐藏错误

Debugging JIT调试在C#应用程序中隐藏错误,debugging,.net-4.0,Debugging,.net 4.0,我有一个在VisualStudio下运行良好的应用程序 但是,当我单独运行它时,不会处理引发异常的特定操作。(该异常是预期的,但在VS下已正确处理) 我在machine.config中添加了一行代码,以启用JIT调试,尝试定位问题,但随后无法重新创建错误(异常已正确处理)。删除该行会导致错误再次出现 我应该如何开始寻找原因 我的代码的相关部分(我相信)位于。一些建议可能会影响您的代码在Visual Studio的不同环境中的行为: 停止Visual Studio在Visual Studio下运

我有一个在VisualStudio下运行良好的应用程序

但是,当我单独运行它时,不会处理引发异常的特定操作。(该异常是预期的,但在VS下已正确处理)

我在machine.config中添加了一行代码,以启用JIT调试,尝试定位问题,但随后无法重新创建错误(异常已正确处理)。删除该行会导致错误再次出现

我应该如何开始寻找原因


我的代码的相关部分(我相信)位于。

一些建议可能会影响您的代码在Visual Studio的不同环境中的行为:

  • 停止Visual Studio在Visual Studio下运行程序时关闭JIT优化器。

    有一个名为“在模块加载时抑制JIT优化”的选项……您希望尝试将其更改为不勾选。

    有关该选项的详细信息,请参见此处:

  • 关闭“托管进程”

  • 运行程序,然后“附加到进程”(这样它就不在托管进程中,模块将被加载并进行JIT优化)

  • 在“异常”对话框中,勾选正在处理/处理的异常的“抛出”复选框…以便您可以跟踪谁在处理它以及为什么要处理它。如果在那里处理异常,则需要安装NET Framework源代码,以便查看详细信息

  • 您可以尝试在WinDBG下运行它(它的行为可能会有所不同,因为您将不会在托管进程(即vshost)下运行)…确保您具有扩展DLL PSSCOR4(如果使用.NET 4),这样您就可以了解情况


因此,我发现了——或者说,一位朋友解释了——这个问题的原因:

当禁用JIT调试时,即使执行看起来是正确的,也无法捕获线程间的异常

正在表单中引发异常。正在关闭事件处理程序:

form.Closing += new delegate
{
    switch(form.DialogResult)
    {
        case DialogResult.OK:
            // do stuff;
            break;
        case DialogResult.Cancel:
            throw new AbortOperationException();
    }
}

// ...

try
{
    mainForm.Invoke(new Function<Form, DialogResult>(form.ShowDialog), mainWindow);
}
catch (AbortOperationException)
{
    // handle abort
}

选项未勾选,在VS下仍然正确处理异常。仍然没有更改。我可以附加到流程中,但据我所知,关于为什么不处理异常,我还没有学到任何新的东西。我已经为这个问题添加了一个围绕抛出和捕获块的代码链接。解决了这个问题,我发现我正试图捕获我现在知道的跨线程的第一次机会异常。你有没有可能发布一些有问题的行?你确定这个bug不依赖于时间吗?听起来可能是这样的,并且您可能有一些只有在运行发行版代码时才满足的竞态条件。@tkeE2036问题是,我不知道有多少代码实际上有问题-有一个
抛出新的MyCustomException(“消息文本”)
表单中。在
try catch(MyCustomException)
块中调用的方法创建的表单上关闭事件处理程序。如果启用了JIT调试,则正确输入catch块。如果JIT被禁用,它就不会被禁用。@tkeE2036好的,我解决了它-我试图捕获我现在知道的第一次机会异常。
form.Closing += new delegate
{
    if (form.DialogResult == DialogResult.OK)
    {
        // do stuff
    }
}

// ...

var result = (DialogResult)mainForm.Invoke(new Function<Form, DialogResult>
if (result == DialogResult.Cancel)
{
    // handle abort
}