V předcházejícím díle o ladících technikách jsem nezodpověděl otázku jak přesně ladící program (debugger) pozná jaký PDB soubor má přiřadit ke spustitelnému souboru. V reakcích na předchozí článek se tento dotaz dokonce objevil.
Odpověď je jednoduchá. Jak jsem zmínil dříve, linker ukládá informaci o tom jaký PDB soubor je nutné použít při ladění modulu do výsledného spustitelného souboru. Pouhé jméno PDB souboru nemůže stačit k jednoznačné identifikaci ladících symbolů v případech kdy sestavujete tentýž program do stále stejného adresáře pod stále stejným jménem. Každá nová verze výsledného programu bude mít přiřazen jedinečný PDB soubor a pouhé jméno tohoto souboru nestačí k jednoznačné identifikaci symbolů které musí ladící program spárovat při ladění.
Linker to řeší cestou nejmenšího odporu. Linker vkládá do výsledného binárního a PDB souboru buďto časovou značku (timestamp) sestavení nebo GUID. Zda je vložena pouze časová značka nebo GUID záleží na verzi sestavovacího programu (linker). Nejnovější verze sestavovacího programu vkládá do souborů GUID a pole „age“ které linker postupně zvyšuje při každém inkrementálním sestavení programu. Pomocí těchto dodatečných informací pak ladící program vyhledá správný soubor symbolů.
Z následující adresářové struktury je pěkně vidět jakým způsobem symbol server organizuje jednotlivé soubory symbolů. Dlouhá čísla na konci cesty jsou GUID generované sestavovacím programem pro jednotlivé verze souboru ntoskrnl.dll:
C:\Library\Symbols\ntoskrnl.pdb\39A56177B07445F28A821DC485C36C7A1 C:\Library\Symbols\ntoskrnl.pdb\67B0240D4CD244299A6DF7979DC9B3701 C:\Library\Symbols\ntoskrnl.pdb\77C608F2ED2B411A9FBF7C9CC6F23D482
Pokud použijete pro ladění program WinDbg pak pomocí příkazu !lmi (Load Module Information) můžete zobrazit informace o tom jaké symboly (PDB soubor) jsou pro ladění daného modulu třeba:
0:000> !lmi test
Loaded Module Info: [test]
Module: Test
Base Address: 00400000
Image Name: Test.exe
Machine Type: 332 (I386)
Time Stamp: 41f2f6ac Sun Jan 23 00:58:20 2005
Size: 2b000
CheckSum: 0
Characteristics: 10f
Debug Data Dirs: Type Size VA Pointer
CODEVIEW 3a, 26780, 16780 RSDS - GUID:
(0x44b43c1e, 0xf472, 0x4d2b, 0x9c, 0x89, 0x99, 0x12, 0x5f, 0xf0, 0x1a, 0x16)
Age: 2, Pdb: c:\Test\Debug\Test.pdb
Image Type: FILE - Image read successfully from debugger.
Test.exe
Symbol Type: PDB - Symbols loaded successfully from image header.
c:\Test\Debug\Test.pdb
Compiler: C++ - front end [13.10 bld 3077] - back end [13.10 bld 3077]
Load Report: private symbols & lines, not source indexed
c:\Test\Debug\Test.pdb
Sekce CODEVIEW je uložena v EXE souboru a obsahuje pole GUID a “age” pomocí nichž ladící program vyhledá soubor symbolů. S pomocí těchto informací byste byli schopni vyhledat správný PDB soubor ručně.