How to get the source file of a compiled method?

I'm really shocked by this!

The StackFrame object ( MSDN Link ) has a GetFileName method that returns the source path of the source file that compiled the executable method (the provided characters were generated and included in the executable assemblies). This information appears to be used to generate the full text of the exception.

I am trying to find a way to get this information if this method is not currently running. I poked around the reflection API and did not see a way to get this information. I guess he's out there somewhere.

Does anyone else know a reflection-based method (or some other method) that can get me the code file name?

Any ideas, comments or abuse are greatly appreciated.

Many thanks!

+6
reflection c #
source share
3 answers

A reflection can provide type information only from assembly metadata. Obtaining the address requires a .pdb debug file and the function address in memory compiled by the JIT compiler. You cannot get the address without the StackFrame.GetNativeOffset () method or the debugger interfaces, assuming the method is even compiled. The latter approach cannot work in the process, the program cannot debug itself.

The CLR does not have any problems, since it can get the address of a method from stack frames when handling an exception. This is still an imperfect art; it cannot see the addresses of the methods that were nested. Having these stack frames is a necessary first step.

+4
source share

You can read the information from the .pdb file and evaluate it yourself. It contains all the necessary data. I have not finished reading the code, but I understand the following:

  • You get a metadata token from the method in question through reflection
  • You are requesting pdb data for this token
  • The pdb entry contains the source file name and line number

The metadata current is a 32-bit number consisting of a type byte and a serial number. This token describes each object in the .NET assembly file: types, reference types, methods, fields, etc. This number costs more than the full namespace, type, method name and method signature, and is easier to process. But keep in mind that it is generated by the compiler and may be different in each assembly, so you always need a .pdb file from the same assembly.

The pdb file contains entries about which IL is biased in which method comes from the source. If you do not have a StackFrame, but only have a method, you will probably find several records about the method so that you can use the one with the least 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 a sample of old Microsoft code:

Since the .NET API for reading .pdb files requires the availability of build files, this conversion must be done immediately after the build in order to keep the generated XML file really portable.

I actually create this method in my .NET logging solution, FieldLog , to allow source location resolution from crash logs from release builds and de-obfuscate stack traces from obfuscated assemblies.

+1
source share

Use the RedGate Reflector decompiler to test the assembly containing the class.

0
source share

All Articles