Whether you are doing pre or post mortem debugging, whether you are using Visual Studio or WinDBG, one of the most important things you can do ( short of not writing the bug in the first place! ) to ready yourself for a productive debugging session is to establish the use of Symbol and Source servers. I’m going to give you some quick pointers of how to make use of these technologies in your day – to – day development process.
What is it? Essentially, a symbol server is way to expose the symbols ( PDBs ) of your applications to the debugger in a way discoverable by the debugger regardless of where the debugger is run. This same thing is also true for system symbols as well. Not only that, it is a way to handle the versioning of those PDBs so that the debugger understands how to find version one of your symbols, vs. version two, and so on.
That’s all well and good, but why is this a good thing for the developer? Let’s look at what things look like when you *don’t* have a symbol server established.
Without Symbol Server
Here’s some sample code you have undoubtedly seen a zillion times by now:
static void Main( string args )
Console.WriteLine( "Hello World" );
Fire up Visual Studio, create an empty C# project, drop in this source, put a break point at the Console.WriteLine line, and hit F5 to start the debugger.
After a moment, you will hit the breakpoint. Now, open up the Modules window ( while in the debugger, select the Debug->Windows->Modules menu item ):
While will open a tool window that looks something like the one below:
The “Modules” tool window shows you all the images ( dlls, etc. ) that are loaded in order to run the executable you are currently debugging. ( NOTE: This is a very useful tool window that many folks don’t know is available in the product, and has many uses which we won’t have a chance to go through today, but more some other time. )
You’ll notice in the image above that there is a Column called “Symbol Status”. Assuming you are running with default debugging settings that Visual Studio 2010 has shipped with, you’ll also notice that almost all the rows in the tool windows except the one I highlighted have the value “Skipped loading symbols.”. The one highlighted is the actual executable itself, which contains the symbols associated with the code you typed in. You’ll also notice that the “User Code” column is “No” for everything except for this last entry as well. More on this later.
Now bring up the “Call Stack” toolwindow ( Debug->Windows->Call Stack ). You should see something like this:
Cool, now let’s see what changes once you start using a Symbol Server, but there is actually one other thing you’ve gotta do before you see the goodness of the Symbol Server. You’ll need to turn off the “Just My Code” feature in Visual Studio.
Turn Off Just My Code
By default, Visual Studio 2010 has the “Just My Code” option turn on. This on on by default as it tends to reduce the amount of information a new user has to deal with when initially debugging inside Visual Studio. It tries to protect you by not drowning you in information.
I struggle with this option, as the intent of it is quite good, but in practice, I tend to always turn this off. ( I would love to hear your thoughts on whether or not this option should be on or off by default. Please fill the comment section with those thoughts! )
For the purposes of this post on this series, please turn off this option. Here’s how:
Go into “Tools-Options…” dialog, find the “Debugging” option on the left side of the dialog, and notice the “Enable Just My Code” option on the right:
Uncheck that box so that your dialog looks like this:
Now your ready to see the effects of the Symbol Server option.
With Symbol Server
Go back into the “Tools->Options…” dialog, and expand the “Debugging” option, and select the “Symbols” option:
Go ahead and click the check box next to “Microsoft Symbol Servers”. You should see a dialog box popup that you can safely ignore for now.
If you hit OK at this point, VS will automatically fill in a default directory that it will use for PDBs it pulls down from a public Microsoft site that contains the PDBs tied to the various versions of the framework DLLs.
If you are on a team of developers, it is a good idea to establish a common file share that all members of your team can use to house these symbols so that you don’t have to wait for the download of those images while you debug. The first developer who needs them would feel that delay, but everyone else on the team would simply pull from the common share.
For now, take the defaults and hit F5 again. You should be in the debugger waiting at the breakpoint.
Take a look at your Modules window now:
Notice how everything is loaded ( Symbol Status column reads “Symbols loaded.” ) and the User Code column reads “N/A”, ‘cause we disabled the “Just My Code Feature”
If you had turned on the Symbol Server options as described above but failed to turn off “Just My Code”, you would have seen something like the following in the Modules window, indicating that symbols were available to be loaded, but Visual Studio did not do so in order to abide by the constraints associated with “Just My Code”. Also, your call stack would look exactly the same as it did before.
Now take a look at your call stack window:
Compare this with the image of the call stack with the one I previously showed you above. Notice how much more information is now available to you?
And therein lies the point of all this:
When you are debugging, you need as much information as you can get in order to figure out the task at hand. You never know what little piece of information will be the clue that drives you towards the final solution.
This post is just scratching the surface. Next post in this series, I’ll dig a little further into some more of the benefits of the symbol server, and why making your own symbols available to your team in this manner will benefit you.