This project is read-only.

Get Original Source Code File Name and Location From IAssembly And PdbReader

Topics: Metadata Model, PDB Reader, Source Model
Dec 2, 2010 at 8:32 PM

Hello,

I am trying to get information about the orignal source code files location (path) and line numbers given entiteis in the metadata model. E.g. For example if I have an IMethodDefintion object can I resolve the filename of the original source code File and a line number for which the defintion occured on? Thanks.

-Greg

 

Dec 2, 2010 at 9:06 PM

The PDB file only records the source locations of executable statements that the debugger can stop on via a breakpoint. For a given method there can be any number of such locations and they can be from more than one document.

Dec 4, 2012 at 9:05 PM

Sorry for digging up this old question. Just to clarify your answer: It is not possible to get the original source file (e.g. Foo.cs) using CCI Metadata? Even if I get multiple source files for a certain Type that would be OK for me.

Dec 4, 2012 at 10:56 PM

As long as the method contains executable statements that have been marked as sequence points for the debugger, you can get source file locations from the PDB.

As of VS2012 you can also get source locations for types and methods via the PDB, using this method defined in the PdbReader class:

    /// <summary>
    /// Returns zero or more locations in primary source documents that correspond to the definition with the given token.
    /// </summary>
    /// <param name="token"></param>
    /// <returns></returns>
    public IEnumerable<IPrimarySourceLocation> GetPrimarySourceLocationsForToken(uint token);

I don't know if any languages other than C# and VB support this, however.
 
To fall back to the pre VS2012 method, you'll have to write your own helper routine and trawl through the IL instructions in the body (if there is a body), looking for IL instructions with matching source locations. Here is a code snippet that does that sort of thing:
          foreach (var sourceLocation in this.sourceLocationProvider.GetPrimarySourceLocationsFor(currentOperation.Location)) {
            if (sourceLocation.StartLine != 0x00feefee) {
              this.lastSourceLocation = sourceLocation;
              break;
            }
          }

 

 

Dec 5, 2012 at 7:06 AM

Thanks for your reply!

I want to find source files that contain more than one type definition. The above approach only seems to work for operations inside methods. Using the locations of a Type does not yield any results. This way I won't be able to check for enums. Is that correct?

 

Dec 14, 2012 at 7:05 PM

If your binaries are produced by C# or VB in VS2012, you can use GetPrimarySourceLocationsForToken(uint token). To get the token, you don't use locations, but you have to downcast your type definitions to IMetadataObjectWithToken. (PeReader produces type definitions that implement this interface).

Dec 17, 2012 at 9:06 AM

Thanks for your help! I noticed that I was trying to reinvent the wheel. StyleCop already has a rule that does exactly what I want to achieve. Just had to hook it up in my project file to get what I needed.

Nov 14, 2013 at 1:10 PM
Ahhh... this is good information to know. I am running into a problem of loading my Assembly, and the ExportedTypes and Locations are both empty. Is this a known issue? I'm simply wanting to read the header of a .pdb and get the root source directory of a project...