With each new version of the Debugging Tools for Windows I’ve always hoped to have an updated version of the Source Indexing tools that are less unfriendly to the end user. Alas, my wait has been in vain, so I decided to write my own version.
Here’s an overview of how to source index symbol files using Debugging Tools for Windows.
The root problem is the Perl scripts are very difficult to decipher, impossible to debug, and do not display much in the way of diagnostic information. As they rely on collecting the stdout of spawned processes, redirecting output to a log file breaks the script functionality, and also suppresses any error messages.
For example, when it spawns p4.exe to find the #have revision of the file, and p4.exe is not in the path, the returned #have revision will be ‘p4.exe is not recognized as an internal or external command’. This is obviously not a valid revision number that Visual Studio can use when debugging!
Perl has been described as a ‘write once’ language meaning that the syntax is so obtuse, not even the original author can read the code after writing it. Although a little harsh, I can easily see how that opinion would be formed!
Using the code
- Visual Studio 2012
- .NET 4.5
- P4API.NET - these assemblies are included, or they can be downloaded from here
- Debugging Tools for Windows is required to use this code - currently distributed with the Windows SDK.
- Sandcastle is required to build the documentation, but the utility will compile and run fine without it.
SourceServerIndexer.exe [-h] [-v] [Symbol File Name]
Which does the following:
- Validates the environment
- Ensures the WindowsSdkDir environment variable exists and points to a valid location.
- Ensures the support tools SrcTool and PdbStr exist.
- Finds the symbol file named on the command line, or recursively searches for all symbol files.
- Processes each symbol file by doing the following
- Calls SrcTool to extract the referenced source files.
- The return code is the number of found source files, and that is used to trim out any diagnostic messages.
- If no source files are found (such as in intermediate symbol files), a warning is emitted and no further processing is done on this file.
- System source file references are removed as these are unlikely to be in source control.
- Any source file that doesn’t have the same root as the current directory is regarded as being a system source file.
- E.g. If the process is running from d:\depot\Application, any file under
f:\dd\vctools\crt_bld\ will be removed.
- Gets #have revision of all remaining source files from Perforce.
- The queries to Perforce are split up into chunk of up to 100 file names at a time to avoid any potential overflows.
- A valid Perforce ticket is presumed to exist (a connection to the Perforce depot has been established at some point by a utility such as p4v).
- For systems that reference multiple Perforce servers and users, some extra work is required to handle credentials seamlessly.
- Creates a source indexing stream using the local path, depot path, and revision number.
- The above Microsoft documentation was invaluable in implementing this.
- The stream is named the same as the symbol file, but with the '.SourceServerTemp' extension.
- Injects the stream into the symbol file with PdbStr.
The Perforce server to use is defined in the executables config file.
Each step is clearly logged to the console to show what it is doing. The ‘-v’ option spews much more information if required – including all spawned command lines
and discovered source files names. All errors are displayed clearly in red.
The code is compiled as ‘Any CPU’ and passes all code analysis tests. The p4bridge
DLL is x64 and assembly resolving is not hooked up to support x86 execution.
All code is documented with the standard C# decoration, and there is a Sandcastle project set up to compile a help file.
Points of Interest
This approach makes configuring the source indexing and adding any new source control providers much easier.
All comments and suggestions are welcome!