I went through the process of setting up a symbol server for our team at work. We develop code in .NET. Different teams were exporting .NET dlls for my team and others to use. We wanted the ability to debug the source. Without the symbols server we would have to sync the source to the correct version of the exported dll and build just to debug. This went on for some time and after much complaining, I looked for other options.
A symbol server ensures that you are able to get pdbs and source code for your dlls or executables from any machine.
Let’s get started
To get started, you will need to have your source stored in source code control. The source control products supported by symbol server out of the box are: Perforce, Visual SourceSafe, Team Foundation Server, Concurrent Versions System, and Subversion. Next, download the Debugging tools for windows which installs to the Program Files directory by default.
Now that you have the debugging tools installed, let’s get familiar with some of the tools you will need to use:
- C:\Program Files\Debugging Tools for Windows (x86)\srcsrv\ssindex.cmd - This is a batch file wrapper around perl scripts that support the souce code control products listed above. This tool is responsible for going through the pdbs and changing the source code file paths inside the pdbs to paths that can be found in source code control. This process is called indexing the pdb.
- C:\Program Files\Debugging Tools for Windows (x86)\symstore.exe - This tool adds the indexed pdbs and dlls to a directory of your choosing. The tool creates version specific directories where the pdbs and dlls are stored. This directory is commonly set up as a file share. This location is where others will point their hungry Visual Studio to download the much needed symbols.
- C:\Program Files\Debugging Tools for Windows (x86)\srcsrv\srctool.exe - This is used mostly to find out if your pdbs were indexed correctly.
- C:\Program Files\Debugging Tools for Windows (x86)\srcsrv\srcsrv.doc - Documentation. Yes, we all read documentation.
Index the pdb
I am going to create a simple windows forms app that everyone on my team is itching to debug. I have checked it into perforce (the source code control we use) and it is ready to be indexed and added to the symbols store.
Before I run ssindex.cmd I must edit C:\Program Files\Debugging Tools for Windows (x86)\srcsrv\srcsrv.ini to tell it where my source code control server lives. It should be straight forward because it is a well documented file.
Now I am ready to run ssindex.cmd like this:
ssindex.cmd -system=p4 -symbols=C:\p4root\addon\Crystal\WindowsFormsApplication1\WindowsFormsApplication1\bin\Debug -source=C:\p4root\addon\Crystal\WindowsFormsApplication1\WindowsFormsApplication1 /debug
The -symbols switch is the directory where my dll and pdb are. The -source switch is the root directory of my source. The /debug just tells it to be verbose (print out stuff). I can tell this worked correctly because it says it wrote the pdb file. For the curious, the way this works is ssindex.cmd calls the command “p4 have” for each source file on the local disk. This returns the path in perforce and version of that file. This is then written into the pdb. We can see these paths if we run srctool.exe on the pdb like:
The first thing to notice is the bottom line which reports that 5 source files where indexed. Above that it lists each file that was indexed along with the “p4 print” command and the perforce path. When you are debugging, it will pull the source from perforce using the print command.
Now that I am confident my source files were indexed properly it is time to add them to a shared folder where my greedy debuggers can get started.
Add to Symbols Store
The tool to use here is symstore.exe. I use it like this:
symstore add /r /f C:\p4root\addon\Crystal\WindowsFormsApplication1\WindowsFormsApplication1\bin\Debug /s C:\Symbols /t app
The symbol store is nothing but a directory structure. The /s switch specifies the root folder to put symbols under. Symstore reports that I have successfully added 3 files to the symbol store. In this case, I am storing the symbols in the directory c:\Symbols as described above by the /s switch. If I look there I will see three directories for each symbol and an admin directory used by the tool for bookkeeping.
If I look inside the pdb dir (the directory highlighted above) I see a guid looking directory. Inside the .exe there is a matching GUID which is how the .exe finds the correct pdb. For the devoted who want to see that value inside the exe or dll, you can run dumpbin /headers on the exe or dll and look for something like:
Debug from another Machine
I want to debug this exe on another box. Let’s fire up Visual Studio 2008 and add a few things. Check enable source server support in the options dialog found in Tools>>Options as shown below.
Go into the symbols option under debugging and add the path to the share where the symbols are located. Also add the directory on your machine where the symbols will be downloaded to. Hit OK.
Now, I will run the exe on my machine. Remember, all I have is the exe and nothing else.
I want to debug what happens when I press the button on my buggy application above. I attach to the exe using Visual Studio. Make sure you have manged code selected in the attach to box.
After I click attach, I can see the symbols have been loaded for the exe using the output window. There is also a modules window accessible from Debug>>Windows in Visual Studio. This will list every dll and whether symbols were loaded. If you right click on a loaded module there are some options to see where symbols were loaded from. This is good for debugging when something goes wrong.
I have successfully attached at this point and now it is time to set a breakpoint using the breakpoint window for the button click event handler. The breakpoint window is under Debug>>Windows>>Breakpoints. Once you have the breakpoint window up, click New then break at function.
When I click on the button in the exe, I get a prompt telling me that VS wants to download the source. I click run.
The source is downloaded and I am debugging just as if the source was built on my machine.
If you are wanting to do this with silverlight you will have to add the registry key below for every machine that wants to pull symbols from the symbol store.
Set RequireFullTrustForSourceServer to 0 (REG_DWORD)
I spent a week with Microsoft support on this one.