I would like to detail here a recent featurette we added to
NDepend v2.9.1: Source files
rebasing. Source files rebasing enables a common CI scenario where the code
is compiled in one location and analyzed in another one.
NDepend needs to access source files during various scenario:
During source file parsing at
analysis time, to fetch comments and cyclomatic complexity metrics values and to
store code elements’ declarations locations.
When clicking Open my declaration in source code of a code element.
When clicking Compare older and
newer versions of source file of a code element.
The
magic of PDB files
To understand the need for Source files rebasing, let’s remind some
details about how the .NET debugger works with source code.
In the .NET world, when one wants to bind with source code from IL code,
one relies on PDB files (Program Database Files). PDB files are built at
compile-time by the C#/VB.NET or C++ compiler. There is one PDB file per .NET
assembly. PDB files contain binary information about where concrete methods (i.e
methods that contain code, as opposed to abstract methods) are declared in
source file and which piece of IL code corresponds to which sequence point. A
sequence point is a contiguous excerpt of a source file that is considered as a
unit of execution from the debugger point of view. Sequence points can thus be
considered as debugger breakpoint because they are meant to be unit of
execution.
As a side note, NDepend uses sequence points to compute the number of lines
of code of a method. Doing so comes with several major benefits explained here: How do you count your number of Lines Of Code (LOC) ?
These source files’ paths contained in PDB represent essential information
for the debugger. Indeed, the debugger relies on this info to bind source code with currently
executed IL code. If you develop on several machines and thus move your source
code from one machine to another, you might have stumble upon the following
VisualStudio message that informs you that source file can’t be found based on the
absolute file paths extracted from the PDB. You can then tell the debugger
where the source file is and it will be smart enough to rebase further absolute
source file path.
A variant is if a source file has been changed and the PDB files hasn’t
been updated since (internally a hash code is used to make possible the synchronization check between source file content and PDB files’ sequence points).
Btw, as many others build process flaws, the fact that PDB files
are not in-sync or source files can’t be found from PDB absolute source files
paths are reported by the NDepend analysis. This feature is part of what we call Build Process health.
Source
files rebasing within NDepend
Basically the underlying problematic is the same with NDepend: source
code might have been compiled in folder A and maybe the analysis occurs on a
different machine, where the source files are in folder B. The absolute source
files’ paths extracted from the PDB are not anymore relevant and NDepend needs
to rebase them, from A to B. This is possible thanks to the following analysis
option:

For maximum flexibility, source file rebasing can be configured when
analysis results have been loaded inside NDepend. This way, analysis results
can be churned from any machine and the users can still go back to source files
declaration at any time, no matter where the source files hierarchy is stored:

As in VisualStudio,
VisualNDepend will be smart enough to ask the user if she wants to rebase a
non-found source file and will apply rebasing delta for further source file
declaration opening.
Another useful scenario is during 2 builds comparison.
Usually, analysis results are done the same way and thus, source files paths are
the same both in older and newer analysis results. In this condition, when trying
to compare 2 versions of a source file NDepend tells that because the 2 paths
are the same, it can’t compare the source files.
A solution to this problem is to fetch the older and the newer source files
hierarchy from the source code repository and rebase both the older and newer application
in VisualNDepend. This way, 2 versions of a source file can be compared
properly.
All the NDepend path code relies on the NDepend.Helpers.FileDirectoryPath
library. Each time I have a look at the extremely poor path handling support of
the .NET Fx I am surprised that
- this library is not so popular
- there is no
other equivalent library proposed (as far as I know)
- MS doesn't seem to consider it as a major room for future improvement.
Don’t other developers need to handle complex
path scenario or does everybody re-invent the wheel?
I think that all tool for .NET developers work more or less this way
when it comes to source files rebasing, as you can read here for the excellent
JetBrain dotTrace profiler.
Posted
08-21-2008 7:16 PM
by
Patrick Smacchia