你可能會想知道的關於 .PDB 檔的一些事

.PDB 檔是什麼?

Program DataBase file 的縮寫

  1. 編譯過程中會產生
  2. 儲存所有模組 (module) 中符號跟位址的清單、檔案名稱、符號定義的行號
  3. 通常在編譯期間從原始碼建立 PDB 文件。它儲存模組中所有符號的列表及位址以及檔案名稱和定義符號的行號。

.PDB 檔中有什麼資料?

  1. 區域變數名稱
  2. 程式碼檔案名稱
  3. 程式碼行號
  4. 程式碼索引

    會將命令嵌入 pdb 中,可以參考這篇Source Indexing and Symbol Servers: A Guide to Easier Debugging

如何確認內容

  1. 使用 Dia2Dump

    可以參考阿尼文章-.pdb 檔案的內容

    以 Visual Studio 2015 為例

    • 1-1. 開啟 %ProgramFiles(x86)%\Microsoft Visual Studio 14.0\DIA SDK\Samples\DIA2Dump\DIA2Dump.sln
    • 1-2. 編譯 (Build)
    • 1-3. 使用 Dia2Dump.exe
      • 1-3-1. 可以進到%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\DIA SDK\Samples\DIA2Dump\x64\Debug\
      • 1-3-2. 直接指定 exe “C:\Program Files (x86)\Microsoft Visual Studio 14.0\DIA SDK\Samples\DIA2Dump\x64\Debug\Dia2Dump.exe”
    • 1-4. Dia2Dump.exe -? 可以查看命令參數

      dia2dump_question

    • 1-5. 參數

      usage: Dia2Dump.exe [ options ] <filename>
      
      參數說明
      -?print this help
      -allprint all the debug info
      -mprint all the mods
      -pprint all the publics
      -gprint all the globals
      -tprint all the types
      -fprint all the files
      -sprint symbols
      -l [RVA [bytes]]print line number info at RVA address in the bytes range
      -cprint section contribution info
      -dbgdump debug streams
      -injsrc [file]dump injected source
      -sfdump all source files
      -oemdump all OEM specific types
      -fpo [RVA]dump frame pointer omission information for a func addr
      -fpo [symbolname]dump frame pointer omission information for a func symbol
      -compiland [name]dump symbols for this compiland
      -lines <funcname>dump line numbers for this function
      -lines <RVA>dump line numbers for this address
      -type <symbolname>dump this type in detail
      -label <RVA>dump label at RVA
      -sym <symbolname> [childname]dump child information of this symbol
      -sym <RVA> [childname]dump child information of symbol at this addr
      -lsrc <file> [line]dump line numbers for this source file
      -ps <RVA> [-n <number>]dump symbols after this address, default 16
      -psr <RVA> [-n <number>]dump symbols before this address, default 16
      -annotations <RVA>dump annotation symbol for this RVA
      -maptosrc <RVA>dump src RVA for this image RVA
      -mapfromsrc <RVA>dump image RVA for src RVA
    • 1-6. 取得所有內容

      "%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\DIA SDK\Samples\DIA2Dum
      p\x64\Debug\Dia2Dump.exe" -all C:\tt.pdb
      

      PDB_ALL

      • 有 source code file 位置跟行號資訊

        pdb_file_lines

PDB 如檔如何被載入

程式碼編譯成 dll 或是 exe 的二進位檔(binary)時,會將 PDB 路徑存入 binary 中 ,並產生一組 GUID遞增 Age 同時封裝進 binary 及 PDB 中, 透過比對 GUIDAge 就可以識別 binary 與 PDB 版本是否相同(如果程式碼未異動,重新編譯的過程仍會重新產生 GUID遞增 Age 並封裝,因此可能造成 PDB 無法使用)

  1. 執行階段

    pdb 需與 執行檔在同一個資料夾中,才會直接出現錯誤的行號

  2. debug the program 載入順序

    • 2-1. 二進位檔中 (exe or dll) 中所封裝的 PDB 路徑
    • 2-2. 二進位檔的所在路徑中(只能在同資料夾中)

      error

      debug1

      debug

    • 修改 .pdb 檔名就會對應不到

      notfound

  3. Visual Studio Debugger 載入順序

    • 3-1. 二進位檔中 (exe or dll) 中所封裝的 PDB 路徑
    • 3-2. 二進位檔的所在路徑中(只能在同資料夾中)
    • 3-3. 組件(assembly)載入的路徑
    • 3-4. 符號儲存快取
    • 3-5. 符號儲存的路徑

    二進位檔中 (exe or dll) 中所封裝的 PDB 路徑

    pdbpathinbinary

Visual Studio 設定符號位置

  1. Tools –> Options..

    toolsoption

  2. Debugging –> Symbols

    debugging

  3. Symbol file(.pdb) locations

    location

原始檔已被修改

  • 會造成 debug 位置不在正確的位置上

    pdbmismatch

    debuglocationerror

手動產出 .pdb

"%ProgramFiles(x86)%\MSBuild\14.0\bin\csc.exe" /out:D:\My.exe /debug /pdb:C:\tt.pdb "C:\Program.cs"
  • 可以透 csc 指令來指定 binary 跟 pdb 的位置

Build Setting 的影響

  1. none

    不會產生 pdb

  2. full

    pdb,且會產生可偵錯的程式碼(會產生 DebuggableAttribute 來通知 JIT 編譯器有可用的偵錯資訊)

  3. pdb-only

    僅產生 pdb ,但無法偵錯

參考資料

  1. MSDN
  2. Know Program Database file (PDB)
  3. Command-line Building With csc.exe
  4. Source Indexing and Symbol Servers: A Guide to Easier Debugging
  5. How to Inspect the Content of a Program Database (PDB) File
  6. PDB Files: What Every Developer Must Know
  7. MATCHING DEBUG INFORMATION
  8. Advanced .NET Debugging - PDBs and Symbol Stores