any generic way to trace/log values of all local variables when an exception occurs in a method? (in C# 3)
You can't, basically. Reflection lets you get at instance (and static) variables but if you want to log local variables, you'll have to do so explicitly. It's possible that you could do a bit better using the profiling API, but that would be a pretty extreme step.
You could do a memory dump of the process since that captures both the heaps and the stacks, but since you tagged the question as logging, I assume that is not what you're looking for.
However, you can reduce the need for this information by making sure your methods are always small and to the point. That will yield much more useful stack traces and it will limit the number of locals to inspect.
Use MiniDumpWriteDump to create a memory dump of the process at the point of the exception. You would have to P/Invoke it.
This question has come up a few times. If ever a bounty were needed, this would be it.
SO points, $$$, pretty girls/hot guys, a ticker-tape parade, a national holiday -- whoever has an implementation with an easy interface deserves it all!!
Answer: Using PostSharp (Policy Injection), XTraceMethodBoundary attribute, override OnException . this logs all the method input and return parameters types and values. I modified PostSharp to add a simple method to log parameters. not perfect but good enough
private static void TraceMethodArguments(MethodExecutionEventArgs eventArgs)
{
object[] parameters = eventArgs.GetReadOnlyArgumentArray();
if (parameters != null)
{
string paramValue = null;
foreach (object p in parameters)
{
Type _type = p.GetType();
if (_type == typeof(string) || _type == typeof(int) || _type == typeof(double) || _type == typeof(decimal))
{
paramValue = (string)p;
}
else if (_type == typeof(XmlDocument))
{
paramValue = ((XmlDocument)p).OuterXml;
}
else
{ //try to serialize
try
{
XmlSerializer _serializer = new XmlSerializer(p.GetType());
StringWriter _strWriter = new StringWriter();
_serializer.Serialize(_strWriter, p);
paramValue = _strWriter.ToString();
}
catch
{
paramValue = "Unable to Serialize Parameter";
}
}
Trace.TraceInformation("[" + Process.GetCurrentProcess().Id + "-" + Thread.CurrentThread.ManagedThreadId.ToString() + "]" + " Parameter: " + paramValue);
}
}
}