23

In a .NET application I have some points where I need to collect some debug info about the current thread state. I can obtain some information new StackTrace() constructor. In particular, I can get the list of current stack frames, including corresponding MethodInfo objects, which can provide me the IL code, the number of local variables and parameters and parameter names.

How can I get current values of these locals and parameters (at least of primitive types)?

I am not able to manually attach any debuggers to the application, but the application can spawn new processes if needed.

X.C.
  • 391
  • 1
  • 5
  • 1
    have a look at http://stackoverflow.com/questions/75076/obtain-parameter-values-from-stackframe-in-net?rq=1. – NeddySpaghetti May 27 '13 at 04:18
  • 6
    That's just not possible, local variables and method arguments are heavily optimized by the jitter. Out of reach from reflection. Only a debugger has a shot at inspecting their values, it knows where to read them. Usually, it still doesn't work for the Release build. – Hans Passant May 27 '13 at 09:22
  • @X.C. You could save them to a run data class, and print that to a file... – Blaze Phoenix Jul 24 '13 at 21:18
  • Is there a specific reason why you are not able to attach a debugger? What about remote debugging? – Marcel Aug 09 '13 at 07:15
  • In your case, is this done as a response to a local exception being caught? Could Exception.Data help? http://msdn.microsoft.com/en-us/library/system.exception.data.aspx – Jason Koopmans Aug 14 '13 at 00:18

5 Answers5

2

Reflection, what you are using to obtain MethodInfo and other details, uses metadata created at compile time -- that is, the data you are accessing has no relation to run-time data, which is what you want.

You mentioned that you can't use a debugger, and you're right, because in production code there's usually no debug symbols loaded in your assembly; a debugger would be no use there.

A important thing here is that, per .NET architecture, once you run an assembly, a "jitter" runs and transforms your IL code into native code; The result is that what is loaded in memory is pure machine code that you can't very easily hack into to obtain values (although theoretically possible). Another point mentioned are optimizations - as long as they are on, you can expect methods to disappear (being inlined), execution order may be changed and variables replaced by literals. The compiler does a lot of stuff to get your code to run faster.


Although I can't see a good solution for obtaining locals' values in run-time, I think there are ways to obtain parameters' value using interception techniques. Take a look at what PostSharp can do for you.

Bruno Brant
  • 8,226
  • 7
  • 45
  • 90
0

You would have to use this on the method involved such that the inlining doesn't prevent you from seeing what you want to see.

MethodImplOptions.NoInlining

Usually, for other local information, you use a logger to a db or flat file or something of that nature.

Maslow
  • 18,464
  • 20
  • 106
  • 193
0

Logging should be fairly simple. Either create a log file or do a WriteLine().

This documentation may help-- http://msdn.microsoft.com/en-us/library/tss153kw.aspx

Irsal
  • 156
  • 6
0

An excellent choice is to use Postsharp. It is based on Aspect Oriented Programming and Code Injection. It allos you to take the parameters values in method.

Maybe can solve part of your needs.

cvillalobosm
  • 156
  • 2
  • 12
-1

Are you able to write the values of your variables to the console, or to a log file?

System.Diagnostics.Debug.WriteLine("Value of my variable: "+myvariable);
Console.WriteLine("Value of my variable: "+myvariable);
msm8bball
  • 79
  • 1
  • 2