5

I want to use ELMAH to log an exception (without throwing it all the way up the call stack) and it log the entire call stack.

Example code:

    protected void Page_Load(object sender, EventArgs e)
    {
        DoSomething();
    }

    private void DoSomething()
    {
        try { TrySomething(); }
        catch (Exception ex) { LogException(ex); }
    }

    private void TrySomething()
    {
        throw new NotImplementedException();
    }

    public static void LogException(Exception ex)
    {
        var currentStack = new System.Diagnostics.StackTrace(true);
        Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
    }

Now, within the LogException method I can see the call stack telling me DoSomething() called TrySomething(), and that threw the exception, but I can't see the call stack showing me Page_Load() called DoSomething(). I want to be able to see the full calling stack.

Example of what ex.StackTrace looks like inside LogException method:

at WebApplication1._Default.TrySomething() in C:\Projects\test\GeneralTests\WebApplication1\Default.aspx.cs:line 26
at WebApplication1._Default.DoSomething() in C:\Projects\test\GeneralTests\WebApplication1\Default.aspx.cs:line 20

I can get the full call stack from System.Diagnostics.StackTrace(), for example:

at WebApplication1._Default.LogException(Exception ex)
at WebApplication1._Default.DoSomething()
at WebApplication1._Default.Page_Load(Object sender, EventArgs e)
[snip]

(and I can get line numbers and source file details by walking each frame of StackTrace)

But how do I inject this into the Exception or raise a new Exception with this call stack detail? Is there an elegant way to do this? Have I missed something really obvious?!

Alex
  • 2,815
  • 2
  • 24
  • 22
  • Check out these answers on related questions that provide a better understanding on why you don't get the full call stack: http://stackoverflow.com/a/6094700/945456 and http://stackoverflow.com/a/24297684/945456 – Jeff B Jul 14 '16 at 19:04

3 Answers3

6

You can do something like this to get the full stack when an error ocurrs:

var currentStack = new System.Diagnostics.StackTrace(true);
return currentStack.ToString();
KingOfHypocrites
  • 9,316
  • 9
  • 47
  • 69
2

When the app is compiled without debug flags, the stack is not necessarily preserved in execution. You can only guarantee each item being recorded by adding try / catch to every method.

cjk
  • 45,739
  • 9
  • 81
  • 112
  • Do you mean that method calls could be inlined into the execution sequence? Otherwise I'm not sure I understand what you're saying - the call stack has to be preserved!? – Alex Oct 11 '10 at 12:03
  • Yes, I think it is inlining. Try / catch will get around it, or always building in debug mode. – cjk Oct 11 '10 at 12:44
  • @Alex: he means that the compiler (and the JIT) often optimizes your code by inlining methods (though you can prevent this using the MethodImplAttribute); in this case you won't get a complete stack trace. – ShdNx Oct 11 '10 at 12:44
  • I have debug info set to pdb-only when in release mode. I have no idea if the compiler marks inlined methods in some way that it can be unravelled/fully debugged - it sounds possible.. Anyway, the question is still relevant for full debug versions where the full calling stack is definitely available. Any further help much appreciated. Thanks guys – Alex Oct 11 '10 at 12:59
  • PS. You're absolutely right, I've just been reading up about code being inlined when compiled as optimised (non-debug, release mode) and it not showing in the call stack. So its use would be clearly limiting. Thanks again – Alex Oct 11 '10 at 13:35
1

Have you looked at the results of Exception.ToString()? It includes a stack trace. Does it include the kind that you're looking for?

BlueMonkMN
  • 25,079
  • 9
  • 80
  • 146
  • 4
    ex.StackTrace is a string representation of the current (inner) call stack, however it doesn't show me the stack outside the exception. I'll update the question body with the results of ex.StackTrace and what I'm after – Alex Oct 11 '10 at 13:07