Reputation: 108
I'm really stumped by this one!
The StackFrame object (MSDN Link) has a GetFileName method that returns the original path of the source file that compiled the executing method (provided symbols were generated and included with the executing assemblies). It looks like this information is used to generate full exception text.
I'm trying to find a way to get at this information if the method isn't currently executing. I've been poking around the reflection API and haven't seen a way to get at this information. I assume it must be in there somewhere.
Does anyone else know of a reflection based method (or indeed any other method) that can get me the code file name?
Any ideas, comments or abuse gratefully accepted.
Many thanks!
Upvotes: 8
Views: 844
Reputation: 20384
You can read the information from the .pdb file and evaluate it yourself. It contains all the data you need. I haven't finished reading the code but my understanding is this:
A metadata token is a 32 bit number that consists of a type byte and a serial number. That token describes every single entity in a .NET assembly file: types, type references, methods, fields, and so on. That number is worth more than the full namespace, type, method name and signature of a method, and it's easier to handle. But be aware that it's generated by the compiler and may be different in every build, so you always need the .pdb file from the same build.
The pdb file contains entries about which IL offset in what method comes from which source location. If you don't have a StackFrame but only a method, you'll probably find multiple entries about the method so you can either use the one with the smallest offset, or describe the entire range in the source code that defines the method.
Here are some links for further reading, the search term is "pdb2xml" which is an old code sample by Microsoft:
Since the .NET API for reading .pdb files requires to have the assembly files available, this conversion should be done directly after the build to keep the generated XML file really portable.
I'm actually building this method in my .NET logging solution, FieldLog, to allow source location resolution from crash logs from release builds, and to de-obfuscate stack traces from obfuscated assemblies.
Upvotes: 2
Reputation: 941565
Reflection can only provide type information from the assembly metadata. Getting the address requires the .pdb debugging file and the address of the function in memory, as compiled by the JIT compiler. You can't get the address without the StackFrame.GetNativeOffset() method or the debugger interfaces, assuming the method is even compiled. The latter approach can't work in-process, a program cannot debug itself.
The CLR doesn't have any trouble because it can retrieve the method address from the stack frames when it processes the exception. That's still an imperfect art, it cannot see addresses of methods that were inlined. Having those stack frames is the required first step.
Upvotes: 4
Reputation: 3785
Use RedGate Reflector decompiler to inspect the assembly containing the class.
Upvotes: 0