Values of local variables in C# after exception?
RedGate has an error reporting tool that says it can
"Get a complete state of your program when it crashed (not just the stack trace), including the values of variables when the crash happened – without having to go back and forth in inefficient email conversations with the end-user."开发者_JAVA技巧
I've built a unhandled exception reporting tool our applications, but I can't imagine how they get more than stack trace information in production code.
Does anyone have any ideas?
It appears that what they do is they rewrite your assembly and add a try/catch block in every method (except ones you specifically exclude). The catch gets the value of all local variables. So if I had the code:
private int Add(int o1, int o2) {
return o1+o2;
}
It would modify it to be something like:
private int Add(int o1, int o2) {
int ret = 0;
try {
ret = o1+o2;
}
catch (Exception e) {
SpecialExceptionHandler.HandleException(e, new object[]{o1, o2});
}
return ret;
}
Pretty tricky... So, it will show the value of the parameters and locals AT THE TIME the exception occurs.
Well, does it say local variables? It doesn't say so in the piece you've quoted. I suspect it does a heap dump and lets you examine the static and instance variables.
Having said that, I suppose they could install some sort of global error handler (there are exception filters which execute even before catch or finally blocks) which grabs the contents of the stack using native code. That could give access to the local variables.
Basically, if it manages to grab the stack before that's unwound (however they do so) they can get at your local variables. If the RedGate code only gets involved when it gets to the top level, I suspect it'll only be heap values.
Have you tried the product for yourself? Could you link to it?
They are not talking about an exception handler but about something that intercedes at the point an exception is thrown.
They're probably taking a crash dump, which includes the entire program memory and all register values, plus a generous amount of metadata. This really does allow you to recover everything about the state of your program when it crashed.
I'm not sure how RedGate is doing it, but Visual Studio 2010 introduced a new feature called IntelliTrace that does something similiar......maybe it's based on that?
It is not possible with pure managed code. You can do this using debug API. May be this helps http://msdn.microsoft.com/en-us/library/bb384652(VS.90).aspx
I don't know the details, but Microsoft provides debugging APIs and a special debugging DLL called SOS for .NET programs. Perhaps RedGate is using such debugging APIs to inspect local variables and other program "roots". It could theoretically use debugging APIs to capture the state of all objects in existence at the time when an exception/crash is detected to be unhandled.
Local variables are stored on the stack (in the same way that parameters are).
精彩评论