I'm reading some crash reports from a UWP application (C#, compiled with .NET Native) and I'm having a hard time understanding the exact syntax/format used in the stack traces. I tried looking for some guides on the internet but I didn't come up with anything useful.
Here are a few examples:
1)
MyProject.ViewModels.SomeViewModel.<OnLogin>d__69.MoveNext()
OnLogin
is the name of a method in SomeViewModel
, so why is it inside angular brackets? Is the "ClassName".<"MethodName>..."
the usual way to indicate an instance method?await
calls into anonymous methods and schedules them using continuations, so I guess that d__69
indicates an async continuation inside the current method.
await
calls, so I guess those numbers aren't sequential. Is it possible to find out the exact part in the original method from that number in the stack trace?MoveNext()
method at the end? What kind of type is it called upon?2)
MyProject.UserControls.SomeControl.<.ctor>b__0_0
.ctor
stands for the object constructor, and looking at the code I found out that b__0_0
stands for an anonymous event handler added inside the constructor, like this: SomeEvent += (s, e) => Foo();
.
0_1
, 1_0
or something else?3) I have this method:
// Returns a Task that immediately throws when awaited, as soon as the token is cancelled
public static Task<T> GetWatchedTask<T>(this Task<T> awaitableTask, CancellationToken token)
{
return awaitableTask.ContinueWith(task => task.GetAwaiter().GetResult(), token);
}
And I have this stack trace:
MyProject.Helpers.Extensions.TasksExtensions.<>c__3$1<System.__Canon>.<GetWatchedTask>b__3_0($Task$1<__Canon> task)
$Task$1
written with the '$' character? Is it like some sort of placeholder/ground indicator (like in a regex) so that it can be used in other places too? (I mean, I see that $1<System.__Canon>
in what I guess is the method return type)
.<>c__3$1<System.__Canon>
mean? From the $1
and on I guess that'd be the Task<T>
return type, but what's that b__3_0
part, since I don't have async calls or event handlers? Does that mean something different in this case?4)
Windows.UI.Xaml.Media.SolidColorBrush..ctor($Color color)
5) I have this other method:
public static async Task<ObservableCollection<SomeCustomClass>> LoadItemGroups(String parentId)
And this stack trace:
MyProject.SQLiteDatabase.SQLiteManager.<>c__DisplayClass142_3.<LoadGroups>b__3()
c__DisplayClass142_3
? Is that a way to indicate the return type with a single type rather than the three separate classes (Task, ObservableCollection, SomeCustomClass)?b__3
here, where in other stack traces it used the format d_xxx
to indicate an async code chunk?Sorry for the many questions, I hope this post will help other UWP C# programmers too.
Thank you in advance for your help!
EDIT: this question should not be considered a duplicate of this other questions because:
Raw data (sometimes called source data, atomic data or primary data) is data that has not been processed for use. A distinction is sometimes made between data and information to the effect that information is the end product of data processing.
Examples of Raw DataA list of every purchase at a store during a month but with no further structure or analysis. Every second of footage recorded by a security camera overnight. The grades of all of the students in a school district for a quarter. A list of every movie being streamed by video streaming company.
The term raw data is used most commonly to refer to information that is gathered for a research study before that information has been transformed or analyzed in any way. The term can apply to the data as soon as they are gathered or after they have been cleaned, but not in any way further transformed or analyzed.
How do I interpret my raw data? Your raw data file contains a list of all SNPs, or genetic markers, you have tested positive for. This means that the file contains a very long list of all the SNPs we have found when running your DNA against our testing chip.
This rule works out well because different file I/O functions are used to write strings and raw data. For writing and reading raw-data, two file I/O functions are fwrite () and fread (). These both work with a file handle returned from a successful fopen () function.
Your raw data file contains a list of all SNPs, or genetic markers, you have tested positive for. This means that the file contains a very long list of all the SNPs we have found when running your DNA against our testing chip.
What is RAW Read Error Rate? RAW Read Error Rate is a SMART disk error that appears only in the traditional hard drives. It doesn’t affect the modern flash storage drives. It’s a critical SMART parameter that indicates problem with the disk surface (platter that stores the data), the actuator arm, and the read/write head.
I bet Eric Lippert will come later and give a better answer, but in case that won't happen - here is my take, because I also got interested in this. The meaning of "d", "c" and similar symbols I got from this answer by Eric Lippert.
1) MyProject.ViewModels.SomeViewModel.<OnLogin>d__69.MoveNext()
This one is relatively simple. OnLogin
is async method, and such methods are rewritten by compiler into a state machine. This state machine implements IAsyncStateMachine
interface which has MoveNext
method. So your async method basically becomes a sequence of MoveNext
invocations of that state machine. That is why you see MoveNext()
in stack trace.
MyProject.ViewModels.SomeViewModel.<OnLogin>d__69
is the name of generated state machine class. Because this state machine is related to OnLogin
method - it becomes part of type name. d
is "iterator class" by the link above. Note that information from link above is 7 years old and is before async\await implementation, but I guess that state machine is similar to iterator (the same MoveNext
method, same principle) - so "iterator class" looks fine. 69 is some unique number \ counter. I guess it's just counter, because if I compile dll with just two async methods - their state machines would be d__0
and d__1
. It's not possible to deduce which part of async method has thrown based on this info.
2) b
is "anonymous method" (link above). I made some experiments and I think first index is related to the method in which anonymous method was used, and second index seems to be related to index of anonymous method inside that method in which they are used. For example suppose you use 2 anonymous methods in constructor and 2 anonymous methods in method Foo
in the same class. Then:
public Test() {
Handler += (s, e) => Foo(); // this will be `b__0_0` because it's first in this method
Handler += (s, e) => Bar(); // this will be `b__0_1` because it's second
}
static void Foo() {
Action a = () => Console.WriteLine("test"); // this is `b__1_0`, 1 refers to it being in another method, not in constructor.
// if we use anonymous method in `Bar()` - it will have this index 2
a();
Action b = () => Console.WriteLine("test2"); // this is `b__1_1`
b();
}
3) This looks quite complicated. First you ask "Why doesn't the second parameter (the token) show up in the signature". That's simple - because method in question represents anonymous method task => task.GetAwaiter().GetResult()
, not your GetWatchedTask
method. Now I was not able to reproduce your stack trace with this one, but still some info. First, System.__Canon
is:
Internal methodtable used to instantiate the "canonical" methodtable for generic instantiations. The name "__Canon" will never been seen by users but it will appear a lot in debugger stack traces involving generics so it is kept deliberately short as to avoid being a nuisance.
Looks cryptic for me, but I guess it kind of represents your T
in runtime. Then, <>c__3$1<System.__Canon>
is <>c__3$1<T>
and is a name of compiler generated class, where "c" is "anonymous method closure class" (from the link above). Such class is generated by compiler when you create a closure, so capture some external state in your anonymous method. What has been captured should be stored somewhere, and it is stored in such class.
Going futher, <GetWatchedTask>b__3_0
is a method in that anonymous class above. It represents your task => task.GetAwaiter().GetResult()
method. Everything from point 2 applies here as well.
I don't know the meaning of $
, maybe it represents number of type parameters. So maybe Task$1<System.__Canon>
means Task<T>
and something like Tuple$2<System.__Canon
would mean Tuple<T1, T2>
.
4) That I unfortunately don't know and was not able to reproduce.
5) c__DisplayClass142_3
is again closure class (see point 3). <LoadGroups>b__3()
is anonymous method you used in method LoadGroups
. So that indicates some anonymous method which is closure (captured external state) and which was called in LoadGroups
method.
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