PDB Files: What Every Developer Must Know

jcgriff2

Co-Founder / Admin
BSOD Instructor/Expert
Microsoft MVP (Ret.)
Staff member
Joined
Feb 19, 2012
Posts
21,541
Location
New Jersey Shore


If you ever looked through your Windbg local symbol cache, you'll find directories and files with PDB extensions.
- MSDN - PDB Files (C++)
- Stack Overflow Forums - What is a PDB file?

PDB, SYS, DLL and others in the local sym cache are rather transparent to most of us as Microsoft Windows OS related symbol files are downloaded during the execution of Windbg or KD and only catch [my] attention when error messages like these appear indicating a problem with a Windows symbol file:
Code:
[COLOR="#000000"]*** WARNING: Unable to verify timestamp for ntoskrnl.exe
*** ERROR: Module load completed but symbols could not be loaded for ntoskrnl.exe[/COLOR]

We're used to seeing such messages for 3rd party drivers & welcome them assuming the named driver solves the BSOD epidemic!

We did experience symbol errors for the Windows NT Kernel about 2 months ago. Contacting Microsoft resulted in a quick fix via adding the new sym files to the MSDL symbol server -

https://www.sysnative.com/forums/bs...skrnl-exe-nt-kernel-symbol-errors-windbg.html


I came upon the following thread at Stack Overflow, which leads to the subsequent one bearing this thread's title. I found the threads interesting as I was able to relate to the OP, even though I am not a driver developer or C++ coder.

My thoughts went out to those here like Mike (writhziden), Richard (niemiro), Ace (AceInfinity) & others that I imagine do face issues like the OP as new releases of their apps are distributed, but obviously not everyone runs the latest version -- thus leaving the door open for a debugging nightmare.


Jere.Jones (Stack Overflow Forum) said:
The software that I write (and sell) is compressed and encrypted before I distribute it.
<...>
It would be helpful if I could use the symbols that I saved from the original build in the debugging of the minidump.

My problem is that I get warnings about being unable to find the right symbols. My research leads me to believe that this is because the checksum of the exe on the client's machine does not match the checksum of the exe that Visual Studio built. And I understand why, it has been compressed and encypted. Of course the checksums don't match.

I figure I can manually edit the minidump or change the checksum of the saved binaries to match the checksum of the distributable. I would prefer to manipulate the stored copies so I don't have to modify every dump that comes in, but I'd be estatic with either.

So, my question is: How can I locate these checksums and figure out what I should replace them with? As an auxiliary question: Is there a better way?
c++ - How can I change a module's checksum in a minidump? - Stack Overflow


Aaron Klotz (Stack Overflow Forum) said:
Without knowing how exactly you are compressing and encrypting your binaries, it's hard for me to be very specific. This blog post by John Robbins points out that executable images are associated with their PDBs via a GUID that's embedded in the executable's PE header. You should be able to view it by running DUMPBIN /HEADERS on the executable, and looking for the output of Debug Directories. If your compression and encryption has modified the PE headers such that this information isn't available (or correct), then it would explain why your debugger can't find anything.

There are a few approaches that I think that you could take to resolve this issue. To really try to get this to work, you might want to consider using WinDbg instead of the Visual Studio debugger. You'll understand why I am recommending this in a moment...

WinDbg provides some options that allow the relaxed loading of symbol files. The idea with this option is that, if the source code hasn't changed but the binaries are from a different build than the PDB, the GUID check can be waived and the mismatched symbol file can be loaded. I don't know how well this will work with your compression and encryption, so YMMV.

WinDbg and its accompanying tools can be used to dump the GUID from both the executable and the PDB, but I'm omitting that for now because I am hoping that those steps won't be necessary.

After you have opened your minidump in WinDbg, you will need to enter several commands into the command line to get this all to work:
Code:
.symopt +0x40
!sym noisy
ld <exe name>
The first command enables the SYMOPT_LOAD_ANYTHING option that skips the GUID check. The !sym command enables verbose output for symbol loading so that you may see more detailed error messages. The ld command directs WinDbg to try to load the symbols for the executable name that you will type in the place of <exe name>. If you repeat the ld command, WinDbg will indicate if it successfully loaded the symbols the first time.

Hopefully this helps -- again, I don't know how well this will work with your compression and encryption, but it's worth trying.

http://stackoverflow.com/posts/1876694/


"This blog post by John Robbins" - Wintellect.com -

PDB Files: What Every Developer Must Know


Most developers realize that PDB files are something that help you debug, but that's about it. Don't feel bad if you don't know what's going on with PDB files because while there is documentation out there, it's scattered around and much of it is for compiler and debugger writers. While it's extremely cool and interesting to write compilers and debuggers, that's probably not your job.

What I want to do here is to put in one place what everyone doing development on a Microsoft operating system has to know when it comes to PDB files. This information also applies to both native and managed developers, though I will mention a trick specific to managed developers. I'll start by talking about PDB file storage as well as the contents. Since the debugger uses the PDB files, I'll discuss exactly how the debugger finds the right PDB file for your binary. Finally, I'll talk about how the debugger looks for the source files when debugging and show you a favorite trick related to how the debugger finds source code. ..........

PDB Files: What Every Developer Must Know | Wintellect




Here is a listing of *.pdb files from my local SYM cache. Not every SYS or DLL has a corresponding PDB file:
Read More:


Complete listing of my current sym cache @ dir level -
Read More:

I've seen checksum symbol errors (rarely) -- could compression & encryption cause this? If so, why aren't more files (e.g., Windows) symbol files affected?
 
I believe you can also gather symbol information through !lmi and !dh extensions.

Code:
1: kd> [COLOR=#008000]!lmi nt[/COLOR]
Loaded Module Info: [nt] 
         Module: ntkrnlmp
   Base Address: fffff80002c0f000
     Image Name: ntkrnlmp.exe
   Machine Type: 34404 (X64)
     Time Stamp: 521ea035 Thu Aug 29 02:13:25 2013
           Size: 5e5000
       CheckSum: 54cbb3
Characteristics: 22  perf
Debug Data Dirs: Type  Size     VA  Pointer
             CODEVIEW    25, 1a1f5c,  1a155c RSDS - GUID: {F69D0006-87EC-491E-87FC-0425D4D378AC}
               Age: 2, Pdb: ntkrnlmp.pdb
                CLSID     4, 1a1f58,  1a1558 [Data not mapped]
     Image Type: MEMORY   - Image read successfully from loaded memory.
    Symbol Type: PDB      - Symbols loaded successfully from symbol server.
                 c:\symbols\ntkrnlmp.pdb\F69D000687EC491E87FC0425D4D378AC2\ntkrnlmp.pdb
    Load Report: public symbols , not source indexed 
                 c:\symbols\ntkrnlmp.pdb\F69D000687EC491E87FC0425D4D378AC2\ntkrnlmp.pdb

I'm also assuming that there isn't symbols for all the data structures available, for example here:

Code:
1: kd> [COLOR=#008000]dt USB_ENDPOINT_DESCRIPTOR[/COLOR]
*************************************************************************
***                                                                   ***
***                                                                   ***
***    Either you specified an unqualified symbol, or your debugger   ***
***    doesn't have full symbol information.  Unqualified symbol      ***
***    resolution is turned off by default. Please either specify a   ***
***    fully qualified symbol module!symbolname, or enable resolution ***
***    of unqualified symbols by typing ".symopt- 100". Note that   ***
***    enabling unqualified symbol resolution with network symbol     ***
***    server shares in the symbol path may cause the debugger to     ***
***    appear to hang for long periods of time when an incorrect      ***
***    symbol name is typed or the network symbol server is down.     ***
***                                                                   ***
***    For some commands to work properly, your symbol path           ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: USB_ENDPOINT_DESCRIPTOR                       ***
***                                                                   ***
*************************************************************************
Symbol USB_ENDPOINT_DESCRIPTOR not found.
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top