We’ve mentioned Symbols in several different posts related to debugging and troubleshooting – but we’ve never actually discussed what symbols are and what they are used for. Today, we’ll rectify that oversight and provide a quick overview of symbol files. Whenever an application or DLL is built, part of the compilation process is the creation of additional files – the symbol files. The symbol files themselves are not needed when running an application. However, if you encounter a situation where you need to debug an application or process, having the symbol files will make your life easier!
Symbol files contain different pieces of information, including:
Names and addresses of global variables
Names and locations of local variables
Function names, and their entry points addresses
Frame Pointer information
Source file paths and line numbers
Type information for variables, structures etc
A single symbol file may contain several hundred symbols. If all of this information was contained within the binary file for the application or DLL itself, the file sizes would be considerably larger. If you have ever had an occasion to install a checked (debug) build of an operating system, you have probably noticed that much more disk space is required than if you were installing the retail build of the same operating system. The reason for this is that the binaries in the checked build include some debugging symbols within the binary itself. Every build of an operating system or application – whether checked or retail, Service Pack 1 or Service Pack 2 has its own set of symbol files and you have to ensure that you match the symbol files with the correct version of your debugging target.
Now let’s talk about public versus private symbols. As the names imply, the private symbols contain more data than the public symbols. The private symbols contain proprietary information such as the source file path and line information. For example, if you were to use public symbols to debug a problem in Notepad, when looking at a stack, you would be able to see the name of the item, the address of the item in virtual memory. However, if you had access to the private symbols, you would also be able to see the data type of each variable, structure and function as well as the type and name of the parameter as well as the source path and line number.
Microsoft makes public symbols available for every version of the operating system. These symbols are available either by using the public symbol server, or as a downloadable package. Each driver shipped with any version of Windows also has public symbols available. Whether you are performing a live debug against an application or operating system or reviewing a dump file, the binary file contains a pointer to the symbol files and the debugger will load the public or private symbol depending on what you are able to access.
Here on the Performance team, we frequently work with customers who are having problems with third-party applications. I suspect that we’ve probably talked to a few of you in the past. The most common problem we encounter is that we have no access to any symbol information for third-party applications. Without that information we have no visibility into what the application is doing … which is why we refer you back to the software vendor for assistance!
With that, it’s time to bring this post to a close. Hopefully this helps you understand what symbols are and why they are so important in debugging.