Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused by the content of Exception.StackTrace

Tags:

c#

clr

Suppose I have the following situation:

9     class Program
10        {
11            public static void WrapperMethod(Action func)
12            {
13                try
14                {
15                    //throw new Exception("Case 1");
16                    func.Invoke();
17                }
18                catch (Exception ex)
19                {
20                    Console.WriteLine(ex.StackTrace);
21                }
22            }
23    
24            static void Main(string[] args)
25            {
26                WrapperMethod(() => { throw new Exception("Case 2"); });
27            }
28        }

I run it and have the following output:

at TestExceptions.Program.<Main>b__0() in c:\users\administrator\documents\visual studio 2010\Projects\TestExceptions\TestExceptions\Program.cs:line 26    
at TestExceptions.Program.WrapperMethod(Action func) in c:\users\administrator\documents\visual studio 2010\Projects\TestExceptions\TestExceptions\Program.cs:line 16

If I uncomment throw new Exception("Case 1"); the output is:

at TestExceptions.Program.WrapperMethod(Action func) in c:\users\administrator\documents\visual studio 2010\Projects\TestExceptions\TestExceptions\Program.cs:line 15

So my question is why in the first case I can see the full path including the Main function while I cannot see the same stuff in the second case. How can I display the more complete information if the production code is similar to the second case scenario.

like image 462
Eugeniu Torica Avatar asked Mar 17 '11 17:03

Eugeniu Torica


2 Answers

What you are seeing in your stack trace is the compiler's generated name for the anonymous function you are passing into WrapperMethod. There is no way to get a "prettier name" in this situation, short of not using anonymous functions.

However, when you know this, it shouldn't be hard to "mentally parse" the mangled Stack Trace. You can recognize the anonymous function by it's name which will be something like <Main>b__0(), and you can tell it was declared inside the Program class because that is where the compiler decided to generate the function.

You are not losing any stack information. If an exception is thrown inside WrapperFunction, that will be the topmost stack frame. If an exception is thrown inside a method that WrapperFunction calls, that (in this case, an anonymous) method will be on top in the stack.

like image 74
driis Avatar answered Sep 30 '22 08:09

driis


In the first case you are making another method call to the anonymous method that is defined inside the Main method. As the exception is thrown inside the anonymous method, it's included in the call stack.

If you throw the exception in the WrapperMethod method, then the anonymous method is never involved, so it won't show up in the call stack.

like image 31
Guffa Avatar answered Sep 30 '22 10:09

Guffa