10

Since pre .NET 4.5 runtimes (including SL/WP) are not async-aware, the stack traces they generate show compiler-generated class/method names (like d_15).

Does anyone know of a utility that generate a better stack trace given a runtime stacktrace, an assembly and a pdb?

To be clear: I'm not looking for a complete async stack, just a better view of which method that actually threw the exception

It seems the above statement is not clear enough, so here is an example:

public async void Foo()
{
    await Bar();
}

public async Task Bar()
{
    async SomethingToMakeThisMethodAsync();

    throw new Exception()
}

When the exception is thrown is Bar, the stacktrace will only contain generated method names (d_15()). I don't care that Foo called Bar. I just want to know that Bar was the method that threw the exception

Richard Szalay
  • 83,269
  • 19
  • 178
  • 237

2 Answers2

4

Andrew Stasyuk has a great article in MSDN magazine http://msdn.microsoft.com/en-us/magazine/jj891052.aspx that details Async Causality Chains as a way to aid in debugging in light of the disjoint and confusing stack traces.

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98
  • Thanks Peter, that could be very useful for tracing the _async_ chain, but I'm just looking for an unmangled stacktrace of the actual (synchronous) stack at the time of the exception - I'm aware that it will stop at the first async boundary. – Richard Szalay May 06 '13 at 00:06
  • 1
    For example, if I see the exception mention `d_12()` I can ILSpy the assembly and disable await support to figure out what method it was in. What I'm looking for is an a tool that performs that task for me. – Richard Szalay May 06 '13 at 00:07
1

Seems like you wasted your rep on bounty since this question was asked few times before, for example, in:

which, as I can recall, had few bounties but had not gotten much further than ref to:

Or in this SO question:

with reference in answer to:

Another similar SO question:

I found the collection of references on Parallel Debugging (Parallel Stacks, Parallel Tasks) in Visual Studio 2010 by Daniel Moth to be very helpful

Update:

Having run your code

using System;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
        Foo();
    }
    public static async void Foo()
    {
      await Bar();
    }

    public static async Task Bar()
    {
      try
      {
        //async SomethingToMakeThisMethodAsync();
        //to make this async
        await TaskEx.Delay(2000);//await Task.Delay(2000);//in .NET 4.5
        throw new Exception();
      }
      catch (Exception)
      {
        throw new Exception("This is Excptn in Bar() method");
      }
    }
  }
}

in VS2010+Async CTP debug mode (F5), I clearly see my identifying exception message "This is Excptn in Bar() method":

enter image description here

enter image description here

Anyway, it is identified as ConsoleApplication1.Program.<Bar> in stack trace (Locals window) even without any additional marking (catching-rethrowing exception with custom message), i.e. having substituted in above code the Bar() method by:

public static async Task Bar()
{
    //async SomethingToMakeThisMethodAsync();
    //to make this async
     await TaskEx.Delay(2000);//await Task.Delay(2000);//in .NET 4.5
     throw new Exception();
}

I see in stack trace that exception was thrown in ConsoleApplication1.Program.<Bar>:

+ $exception    
{System.Exception: Exception of type 'System.Exception' was thrown.

Server stack trace: 
   at ConsoleApplication1.Program.<Bar>d__3.MoveNext() in R:\###Debugging\#seUnmangling (pre .NET 4.5) asyncawait stack traces\AsyncConsole_Sln\1Cons_Prj\Program.cs:line 29

Exception rethrown at [0]: 
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at ConsoleApplication1.Program.<Foo>d__0.MoveNext() in R:\###Debugging\#seUnmangling (pre .NET 4.5) asyncawait stack traces\AsyncConsole_Sln\1Cons_Prj\Program.cs:line 19

Exception rethrown at [1]: 
   at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.<SetException>b__1(Object state)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()}   System.Exception

enter image description here

Community
  • 1
  • 1
  • I haven't wasted my rep - people keep refusing to read the *"to be clear"* section of my question. *I am not looking for an asynchronous callstack.* I want to know which method the _current_ async method is executing in. I'll update my question again to be even clearer. – Richard Szalay May 14 '13 at 02:21
  • 1
    You can catch and rethrow an exception with identifying a methods message (see update in my answer)? – Gennady Vanin Геннадий Ванин May 14 '13 at 17:40