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
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.
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
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":
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With