Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# rethrow an exception: how to get the exception stack in the IDE?

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.

Consider this code:

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

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

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.

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.

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.

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).

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.

like image 661
redtuna Avatar asked Dec 04 '10 01:12

redtuna


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

Is C programming hard?

C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.


3 Answers

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:

  1. Debug » Exceptions... (Ctrl+Alt+E)
  2. Check "Thrown" for the exception types you care about (in this case, Commange Language Runtime Exceptions)
  3. Click OK
  4. Start debugging

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.

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).

like image 191
Chris Schmich Avatar answered Oct 12 '22 00:10

Chris Schmich


If you use ReSharper, you can copy exception stacktrace to clipboard, then choose in the menu: ReSharper > Tools > Browse Stack Trace (Ctrl+E,T). It will show stacktrace with clickable locations, so you'll be able to quickly navigate.


(source: jetbrains.com)

This feature is also very useful while digging through logs from users (if stacktraces of exceptions are logged).

like image 28
Athari Avatar answered Oct 11 '22 23:10

Athari


Not that you should re-throw but here's a blog post about how to preserve the stack trace, essentially it boils down to this:

private static void PreserveStackTrace(Exception exception)
{
  MethodInfo preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace",
    BindingFlags.Instance | BindingFlags.NonPublic);
  preserveStackTrace.Invoke(exception, null);
}

...
catch (Exception ex)
{
  // do something
  // ...
  PreserveStackTrace(ex);
  throw;
}
like image 1
BrokenGlass Avatar answered Oct 12 '22 00:10

BrokenGlass