Getting Debug Symbols even for Retail Builds
Here inside Microsoft we of course have access to private debug symbols to help debug issues like I do in Windows Script as a member of the Customer Product-lifecycle Experience (CPX) team. We use a host of debugging tools like Windbg.exe, ntsd.exe, and even Visual Studio .NET. You can even download some of these debugging tools and related documentation. The download also includes Son of Strike (SOS; sos.dll) in the clr10 directory, which is featured in May’s MSDN Magazine column, JIT and Run: Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects. Note that sos.dll can also be found in the .NET Framework 1.1 installation directory, %WINDIR%\Microsoft.NET\Framework\v1.1.4322.
To easily access the private symbols – with full source and data type information – we use a symbol server. This caches symbols for various builds of executables. You can even create your own symbol server to cache public and private symbols. Search for “symbol servers” in the bundled help files in the download above, debugger.chm.
You can access public symbols for even retail Windows builds (and some other Microsoft applications) by setting the _NT_SYMBOL_PATH environment variable to srv*DownloadStore*http://msdl.microsoft.com/download/symbols, where DownloadStore is a download cache directory (preferrably local) where downloaded symbols are cached. Any debugger you use that makes use of the symbol server DLL like symsrv.dll – for which srv is shorthand for symsrv*symsrv.dll – will download symbols for the build of the module or modules you have loaded.
This string can also be used within the debugger itself. In windbg.exe, for example, you would type the following command:
In Visual Studio .NET, you can open the project properties for a Visual C++ project, select the Debugging property page, and enter the value above in the “Symbol Path” property. When you debug your project, symbols for Windows applications and libraries will be downloaded when their respective modules are loaded. No more must you work against call stacks having to resolve function addresses, but you can now see the functions for Windows executables in the call stack.