Why not to use StackTrace to find what method called you
- by Alex.Davies
Our obfuscator, SmartAssembly, does some pretty crazy reflection. It's an obfuscator, it's sort of its job to do things in the most awkward way possible. But sometimes, you can go too far. One such time is this little gem from the strings encoding feature: StackTrace stackTrace = new StackTrace();
StackFrame frame = stackTrace.GetFrame(1);
Type ownerType = frame.GetMethod().DeclaringType;
It's designed to find the type where the calling method is defined.
A user found that strings encoding occasionally broke on x64 systems. Very strange. After some debugging (thank god for Reflector Pro, it would be impossible to debug processed assemblies without it) I found that the ownerType I got back was wrong.
The reason is that the x64 JIT does tail call optimisation. This saves space on the stack, and speeds things up, by throwing away a method's stack frame if the last thing that it calls is the only thing returned. When this happens, the call to StackTrace faithfully tells you that the calling method is the one that called the one we really wanted.
So using StackTrace isn't safe for anything other than debugging, and it will make your code fail in unpredictable ways. Don't use it!