❔ Get locals and their values from an Exception object.
Is it possible to get the local variables and their values from a
StackTrace
object created from a System.Exception
object?
I have the method public void LogException(ex)
. I'm trying to log all variables names and values. I'm not using compiler optimizations if it matters.
I tried using reflection and a few other crazy things but nothing seems to work properly.
Current code:
21 Replies
no
the stack frames are popped before you ever have a chance to access them I'm pretty sure
thus no local variable information would be available
(someone please correct me if I'm wrong)
That's what I thought! But I keep finding stackoverflow articles that claim that it's available if compiler optimizations are turned off. I have all optimizations off in debug mode which is where this code will be used.
if anything you're relying on undefined behaviour so
how so?
local variables will be on stack / registers
once the stack gets unwound it is very likely that they get overwritten pretty soon
especially registers
If that's the case, how does the visual studio debugger correctly tell me the locals when it catches the exceptions?
Because it pauses execution before the stack unwinds
You mention the vs debugger pauses execution before the stack unwinds. I'm still a bit confused.
Stack information is already saved to the StackTrace object in my LogException. Are you implying execution is never halted while the exception instance is created? That makes no sense for a single-threaded app. Even so there should be a way to do it the same way visual studio does it if that's the only possibility.
I've seen people claim it's possible on stackoverflow but their example code is just too difficult for me to understand or their use case is too far from mine to be useable.
A new exception is thrown, Visual Studio is notified of this and is able to pause execution
why does pausing execution matter when the stacktrace obj is already saved to a var?
the saving is instantaneous so it should be the same as pausing?
Because the stack trace is just info about the individual steps taken to get to the point where the exception occurred
It's meant purely for things like printing the stack trace as debug info
this 7 year old answer claims to be able to do it using PostSharp:
https://stackoverflow.com/questions/362124/how-to-trace-all-local-variables-when-an-exception-occurs
Stack Overflow
How to Trace all local variables when an exception occurs
any generic way to trace/log values of all local variables when an exception occurs in a method?
(in C# 3)
jeez, C# 3
- A
throw
statement/expression is reached
- A new exception object is created
- The current stack trace is stored into the exception
- The debugger is notified of the exception
- The stack unwinds
Local variables aren't saved at any point during thisbasically I created an app and added a boatload of LogException calls. Users keep sending me their logs but the stacktrace I'm logging is beyond useless as it doesn't have any locals. Yes I know it fails at this line in method x, but it doesn't help me unless I know what the value is.
Been trying to update my code to just verbosely log all locals I need, but I'm 3 hours into that project and I'm not even a quarter of the way done. So I'm out of ideas if this get-locals-from-stacktrace idea isn't possible.
it's not like I can even send them manually either. Take this example:
Wouldn't work because x is in a different scope
Thank you for the analysis. I think I'm understanding the problem a bit better now
A lot of answers recommend either PostSharp, IntelliTrace, Minidumps, or some sort of reflection.
Those probably could work, but imo they'd be overkill
What do you recommend? Idk how to read dump files, but would that solve my problem?
I don't really know, but my guess would be to have better logging in and around methods which might commonly throw.
i miss python's
locals()
dunno what this postsharp thing is but it seems to rewrite IL
so that's doing it in a completely different way
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.