C#中重新抛出异常:如何让在IDE中异常堆栈?异常、堆栈、抛出、IDE

2023-09-03 03:14:36 作者:难得喜欢

还有曾在这里被讨论之前要重新抛出异常的正确方法。这个问题,取而代之的,是如何从Visual Studio中重新抛出的时候获得有用的行为。

There has been discussion here before about the correct way to rethrow an exception. This question, instead, is about how to get useful behavior from Visual Studio when using rethrow.

考虑这个code:

   static void foo() {
        throw new Exception("boo!");
    }

    static void Main(string[] args) {
        try {
            foo();
        } catch (Exception x) {
            // do some stuff
            throw;
        }
    }

这出来的异常有正确的堆栈跟踪,显示FOO()作为例外的来源。 然而的,在GUI调用堆栈窗口只显示主,而我期待它显示了异常的调用堆栈,所有到foo的方式。

The exception that comes out has the correct stack trace, showing foo() as the source of the exception. However, the GUI Call Stack window only shows Main, whereas I was expecting it to show the exception's call stack, all the way to foo.

在没有重新抛出,我可以使用GUI非常快速导航调用栈,看看什么叫导致异常,以及我们如何到达那里。

When there is no rethrow, I can use the GUI to very quickly navigate the call stack to see what call caused the exception and how we got there.

随着重新抛出我希望能够做同样的事情。相反,调用堆栈的GUI显示是没有用的我。我得异常详细信息复制到剪贴板,将其粘贴到记事本,然后手动导航到调用堆栈我感兴趣的任何功能。

With the rethrow I'd like to be able to do the same thing. Instead, the call stack that the GUI shows is of no use to me. I have to copy the exception details to the clipboard, paste it to Notepad, and then manually navigate to whichever function of the call stack I'm interested in.

顺便说一句,我得到同样的行为,如果我加入 [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] 或者如果我改变渔获只是赶上(例外)

By the way, I get the same behavior if I add [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] or if I change the catch to just catch (Exception).

我的问题是:考虑到code我已经使用重新抛出,有人可以提出一个方便的方式来浏览与异常关联的调用堆栈?我使用Visual Studio 2010。

My question is: given that the code I have uses rethrow, can someone suggest a convenient way to navigate the call stack associated with the exception? I'm using Visual Studio 2010.

推荐答案

主要的调试器中断因为这个异常是未处理。默认情况下,调试器将只打破未处理的异常。一旦你停在,从原始异常的调用堆栈是present在异常,但所有其他上下文已经丢失(如当地人,堆/内存状态)。

The debugger breaks at the throw in Main because that exception is unhandled. By default, the debugger will only break on unhandled exceptions. Once you've stopped at Main, the call stack for the original exception from foo is present in the exception, but all of the other context has been lost (e.g. locals, stack/memory state).

这听起来像你想的调试器打破了抛出,所以你应该告诉调试器打破第一次机会异常:

It sounds like you want the debugger to break on the throw in foo, so you should tell the debugger to break on first-chance exceptions:

在调试»例外...(控制 + 替代 + 电子) 检查抛出为你关心的异常类型(在这种情况下,Commange语言运行库异常) 单击OK(确定) 在开始调试 Debug » Exceptions... (Ctrl+Alt+E) Check "Thrown" for the exception types you care about (in this case, Commange Language Runtime Exceptions) Click OK Start debugging

在这种情况下,调试器将立即打破时,引发异常。现在,您可以检查堆栈,本地人等,在原始异常的情况下。如果继续执行( F5 ),调试器将再次突破上重新抛出的主要

In this case, the debugger will break immediately when foo throws an exception. Now, you can examine the stack, locals, etc., in the context of the original exception. If you continue execution (F5), the debugger will break again on the rethrow in Main.

以另一种方法,如果你正在运行VS2010旗舰版,您还可以使用的IntelliTrace为调试倒退看在异常的时间参数,线程和变量。请参见这个MSDN文章细节。 (全面披露:我工作在一个团队密切相关的IntelliTrace)。

Taking another approach, if you're running VS2010 Ultimate, you can also use IntelliTrace to "debug backwards" to see parameters, threads, and variables at the time of the exception. See this MSDN article for details. (Full disclosure: I work on a team closely related to IntelliTrace).