Fixing Symbols in WinDbg

 

I had instrumented a driver to capture certain file system related data in Windows kernel and it happened that there were some problems using the binary. I rebuilt it without any code changes and deleted the old data. At the problem site, the original binary was used for which I deleted symbols. The problem now – how do I analyze data without right symbols? Though the symbols for new and old binaries must be same, WinDbg would not load them for mismatch in timestamp.

From the huge set of commands that empower WinDbg, there is one – .symopt that helps control WindDbg behaviour relative to symbols loading. Setting SYMOPT_LOAD_ANYTHING symopt, I was able to load new symbols for old binary.

3: kd> .symopt
Symbol options are 0x30237:
  0x00000001 – SYMOPT_CASE_INSENSITIVE
  0x00000002 – SYMOPT_UNDNAME
  0x00000004 – SYMOPT_DEFERRED_LOADS
  0x00000010 – SYMOPT_LOAD_LINES
  0x00000020 – SYMOPT_OMAP_FIND_NEAREST
  0x00000200 – SYMOPT_FAIL_CRITICAL_ERRORS
  0x00010000 – SYMOPT_AUTO_PUBLICS
  0x00020000 – SYMOPT_NO_IMAGE_SEARCH

//Set SYMOPT_LOAD_ANYTHING option
3: kd> .symopt +0x40
Symbol options are 0x30277:
  0x00000001 – SYMOPT_CASE_INSENSITIVE
  0x00000002 – SYMOPT_UNDNAME
  0x00000004 – SYMOPT_DEFERRED_LOADS
  0x00000010 – SYMOPT_LOAD_LINES
  0x00000020 – SYMOPT_OMAP_FIND_NEAREST
  0x00000040 – SYMOPT_LOAD_ANYTHING
  0x00000200 – SYMOPT_FAIL_CRITICAL_ERRORS
  0x00010000 – SYMOPT_AUTO_PUBLICS
  0x00020000 – SYMOPT_NO_IMAGE_SEARCH

Once you have the symbols loaded, you can use !chksym or !itoldyouso debugger extension to know where the symbol is loaded from.

3: kd> !chksym NDIS

NDIS.sys
    Timestamp: 45D699F1
  SizeOfImage: 66000
          pdb: ndis.pdb
      pdb sig: 241CA1AD-7B6A-4BFF-B215-CD5C57E63679
          age: 2

Loaded pdb is \MySymServersymbolsndis.pdb241CA1AD7B6A4BFFB215CD5C57E636792ndis.pdb

ndis.pdb
      pdb sig: 241CA1AD-7B6A-4BFF-B215-CD5C57E63679
          age: 2

MATCH: ndis.pdb and NDIS.sys

.symopt command can be used to display or set symbol loading options for windows debugger. Some of the interesting options are discussed below.

.SYMOPT

Flag

Option

Detail

     

0x4

SYMOPT_DEFERRED_LOADS

Symbols are loaded only when needed

0x10

SYMOPT_LOAD_LINES

Reads line number information from source file, this must be turned on when using source debugging

0x20

SYMOPT_OMAP_FIND_NEAREST

If you do not find symbols at the expected location for some reason, this option loads the nearest match.

0x40

SYMOPT_LOAD_ANYTHING

Allows debugger to load symbols with timestamp mismatches

0x80

SYMOPT_IGNORE_CVREC

Symbol handler ignores CV record of loaded modules while searching for symbols

0x100

SYMOPT_NO_UNQUALIFIED_LOADS

Debugger will match symbols from already loaded modules only and won’t try to auto load modules. Thus debugger will respond fast to mistyped symbols as it won’t go on searching all unloaded symbol files.

0x400

SYMOPT_EXACT_SYMBOLS

Debugger will only load symbols that exactly matches.

0x10000

SYMOPT_AUTO_PUBLICS

Enables debugger to search for a symbol in private symbol table and if no match is found, only then will it search in public symbol table.

0x80000000

SYMOPT_DEBUG

Turns on noisy symbol load, !sym noisy and !sym quiet toggles this.

     

Following are ON by default for WinDbg

0x00000001 – SYMOPT_CASE_INSENSITIVE
0x00000002 – SYMOPT_UNDNAME
0x00000004 – SYMOPT_DEFERRED_LOADS
0x00000010 – SYMOPT_LOAD_LINES
0x00000020 – SYMOPT_OMAP_FIND_NEAREST
0x00000200 – SYMOPT_FAIL_CRITICAL_ERRORS
0x00010000 – SYMOPT_AUTO_PUBLICS
0x00020000 – SYMOPT_NO_IMAGE_SEARCH

Command line options that work with both Kd.exe and WinDbg are

    • -s disables lazy symbol loading
    • -ses enables strict symbol loading
    • -sflags <flags> sets symbol flags from a numeric argument
    • -snul disables automatic symbol loading for unqualified names
    • -sup enables full public symbol searches
    • -y <SymbolsPath> specifies the symbol search path (see _NT_SYMBOL_PATH)

Another interesting command is !lmi, <module> which generates detailed output about a module. This is my preferred choice over lm vm <module>. !lmi analyzes module headers and generates a formatted summary of the information found there. But if module header is not there in memory dump (paged out), an error will be generated.

3: kd> !lmi NDIS
Loaded Module Info: [ndis]
         Module: NDIS
   Base Address: fffffadf902a1000
Image Name: NDIS.sys
   Machine Type: 34404 (X64)
Time Stamp: 45d699f1 Sat Feb 17 11:30:17 2007
Size: 66000
       CheckSum: 592ef
Characteristics: 22  perf
Debug Data Dirs: Type  Size     VA  Pointer
             CODEVIEW    21, 10b74,   10174 RSDS –
GUID: {241CA1AD-7B6A-4BFF-B215-CD5C57E63679}
               Age: 2, Pdb: ndis.pdb
                CLSID     4, 10b70,   10170 [Data not mapped]
     Image Type: MEMORY   – Image read successfully from loaded memory.
    Symbol Type: PDB      – Symbols loaded successfully from symbol server.
\MySymServersymbolsndis.pdb241CA1AD7B6A4BFFB215CD5C57E636792ndis.pdb
       Compiler: Linker – front end [0.0 bld 0] – back end [8.0 bld 40310]
    Load Report: private symbols & lines, source indexed
\MySymServersymbolsndis.pdb241CA1AD7B6A4BFFB215CD5C57E636792ndis.pdb

PS: I have also seen .reload /i <module> helps load the symbols ignoring any mismatch in pdb versions.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s