Dela via


Offentliga och privata symboler

När en .pdb- eller .dbg-symbolfil i full storlek skapas av en länkare innehåller den två distinkta informationssamlingar: privata symboldata och en offentlig symboltabell. Dessa samlingar skiljer sig åt i listan över objekt som de innehåller och den information de lagrar om varje objekt.

De privata symboldata innehåller följande objekt:

  • Funktionen

  • Globala variabler

  • Lokala variabler

  • Information om användardefinierade strukturer, klasser och datatyper

  • Namnet på källfilen och radnumret i filen som motsvarar varje binär instruktion

Den offentliga symboltabellen innehåller färre objekt:

  • Funktioner (förutom funktioner som deklarerats som statiska)

  • Globala variabler som anges som externa (och andra globala variabler som visas i flera objektfiler)

Som en allmän regel innehåller den offentliga symboltabellen exakt de objekt som är tillgängliga från en källfil till en annan. Objekt som bara visas i en objektfil, till exempel statiska funktioner, variabler som endast är globala i en enda källfil och lokala variabler, ingår inte i den offentliga symboltabellen.

Dessa två datasamlingar skiljer sig också åt i vilken information de innehåller för varje objekt. Följande information ingår vanligtvis för varje objekt som finns i privata symboldata:

  • Namn på artikeln

  • Objektets adress i virtuellt minne

  • Datatyp för varje variabel, struktur och funktion

  • Typer och namn på parametrarna för varje funktion

  • Omfång för varje lokal variabel

  • Symboler som är associerade med varje rad i varje källfil

  • FPO-register (Frame Pointer Omission) för varje funktion som används för att komma åt stacken

Å andra sidan lagrar den offentliga symboltabellen endast följande information om varje objekt som ingår i den:

  • Namnet på objektet.

  • Adressen till objektet i modulens virtuella minnesutrymme. För en funktion är detta adressen till dess startpunkt.

  • FPO-poster (Frame Pointer Omission) för varje funktion.

  • Kan innehålla symbolprefix/suffix som kallas dekorationer.

Offentliga symboldata kan betraktas som en delmängd av privata symboldata på två sätt: de innehåller en kortare lista med objekt och innehåller också mindre information om varje objekt. Till exempel innehåller offentliga symboldata inte lokala variabler alls.

Varje lokal variabel ingår endast i privata symboldata, med dess adress, datatyp och omfång. Funktioner ingår å andra sidan i både privata symboldata och offentliga symboltabeller, men medan privata symboldata innehåller funktionsnamn, adress, FPO-poster, indataparameternamn och -typer och utdatatyp, innehåller den offentliga symboltabellen bara funktionsnamnet, adressen och FPO-posten.

Det finns en annan skillnad mellan privata symboldata och den offentliga symboltabellen. Många av objekten i den offentliga symboltabellen har namn som är dekorerade med ett prefix, ett suffix eller båda. De här dekorationerna läggs till av C-kompilatorn, C++-kompilatorn och MASM-monteringsverktyget. Typiska prefix är en serie understreck eller strängen __imp_ (som anger en importerad funktion). Vanliga suffix är en eller flera vid tecken ( @ ) följt av adresser eller andra identifieringssträngar. Dessa dekorationer används av länkaren för att särskilja symbolen, då det är möjligt att funktionsnamn eller globala variabelnamn kan upprepas i olika moduler. Dessa dekorationer är ett undantag från den allmänna regeln att den offentliga symboltabellen är en delmängd av privata symboldata.

Fullständiga symbolfiler och borttagna symbolfiler

En fullständig symbolfil innehåller både privata symboldata och den offentliga symboltabellen. Den här typen av fil kallas ibland för en privat symbolfil, men det här namnet är missvisande, för en sådan fil innehåller både privata och offentliga symboler.

En borttagen symbolfil är en mindre fil som endast innehåller den offentliga symboltabellen , eller i vissa fall endast en delmängd av den offentliga symboltabellen. Den här filen kallas ibland för en offentlig symbolfil.

Skapa fullständiga och avskalade symbolfiler

Om du skapar dina binärfiler med Visual Studio kan du skapa antingen fullständiga eller avskalade symbolfiler. Information om hur du skapar strippade symboler finns i /PDBSTRIPPED (Strip Private Symbols).

Med verktyget BinPlace kan du skapa en avskalad symbolfil från en fullständig symbolfil. När de vanligaste BinPlace-alternativen används (-a -x -s -n) placeras de avskalade symbolfilerna i katalogen som visas efter -s-växeln och de fullständiga symbolfilerna placeras i katalogen som visas efter -n-växeln . När BinPlace tar bort en symbolfil får de avskalade och fullständiga versionerna av filen identiska signaturer och annan identifierande information. På så sätt kan du använda någon av versionerna för felsökning. Mer information om BinPlace finns i BinPlace.

Med verktyget PDBCopy kan du skapa en avskalad symbolfil från en fullständig symbolfil genom att ta bort privata symboldata. PDBCopy kan också ta bort en angiven delmängd av den offentliga symboltabellen. Mer information finns i PDBCopy.

Med verktyget SymChk kan du avgöra om en symbolfil innehåller privata symboler. Mer information finns i SymChk.

Visa offentliga och privata symboler i felsökningsprogrammet

Du kan använda WinDbg, KD eller CDB för att visa symboler. När ett av dessa felsökare har åtkomst till en fullständig symbolfil, har den både informationen som anges i privata symboldata och informationen som anges i den offentliga symboltabellen. Offentliga symboldata innehåller symboldekorationer.

Vid åtkomst till privata symboler används alltid privata symboldata eftersom dessa symboler inte ingår i den offentliga symboltabellen. Dessa symboler är aldrig dekorerade.

Kommandot .symopt (Ange symbolalternativ) kan användas för att styra symbolalternativen som avgör hur offentliga och privata symboler används av felsökningsprogrammet. Det här kommandot aktiverar till exempel information om felsökning av symboler.

 .symopt+ 0x80000000

Följande alternativ ändrar hur offentliga och privata symboler används i felsökningsprogrammet.

  • När alternativet SYMOPT_UNDNAME är aktiverat inkluderas inte dekorationer när namnet på en offentlig symbol visas. När du söker efter symboler ignoreras dessutom dekorationer. När det här alternativet är inaktiverat visas dekorationer när offentliga symboler visas och dekorationer används i sökningar. Privata symboler är aldrig dekorerade under några omständigheter. Det här alternativet är aktiverat som standard i alla felsökningsprogram.

  • När alternativet SYMOPT_PUBLICS_ONLY är aktiverat ignoreras privata symboldata och endast den offentliga symboltabellen används. Det här alternativet är inaktiverat som standard i alla felsökningsprogram.

  • När alternativet SYMOPT_NO_PUBLICS är aktiverat ignoreras den offentliga symboltabellen och sökningar och symbolinformation använder enbart privata symboldata. Det här alternativet är inaktiverat som standard i alla felsökningsprogram.

  • När alternativet SYMOPT_AUTO_PUBLICS är aktiverat (och både SYMOPT_PUBLICS_ONLY och SYMOPT_NO_PUBLICS är av) utförs den första symbolsökningen i privata symboldata. Om den önskade symbolen hittas där avslutas sökningen. Annars genomsöks den offentliga symboltabellen. Eftersom den offentliga symboltabellen innehåller en delmängd av symbolerna i privata data resulterar detta normalt i att den offentliga symboltabellen ignoreras.

  • När alternativen SYMOPT_PUBLICS_ONLY, SYMOPT_NO_PUBLICS och SYMOPT_AUTO_PUBLICS är inaktiverade genomsöks både privata symboldata och den offentliga symboltabellen varje gång en symbol behövs. Men när matchningar hittas på båda platserna används matchningen i privata symboldata. Beteendet i den här instansen är därför detsamma som när SYMOPT_AUTO_PUBLICS är aktiverat, förutom att användning av SYMOPT_AUTO_PUBLICS kan leda till att symbolsökningar sker något snabbare.

Här är ett exempel där kommandot x (Granska symboler) används tre gånger. Första gången används standardsymbolalternativen, så informationen hämtas från privata symboldata. Observera att detta innehåller information om adress, storlek och datatyp för arrayen typingString. Därefter används kommandot .symopt+ 4000, vilket gör att felsökaren ignorerar privata symboldata. När x-kommandot sedan körs igen används den offentliga symboltabellen. den här gången finns det ingen information om storlek och datatyp för att skrivaString. Slutligen används kommandot .symopt- 2, vilket gör att felsökningsprogrammet inkluderar dekorationer. När x-kommandot körs den sista gången visas den dekorerade versionen av funktionsnamnet _typingString.

0:000> x /t /d *!*typingstring* 
00434420 char [128] TimeTest!typingString = char [128] ""

0:000> .symopt+ 4000

0:000> x /t /d *!*typingstring* 
00434420 <NoType> TimeTest!typingString = <no type information>

0:000> .symopt- 2

0:000> x /t /d *!*typingstring* 
00434420 <NoType> TimeTest!_typingString = <no type information> 

Visa offentliga och privata symboler med DBH-verktyget

Ett annat sätt att visa symboler är att använda DBH-verktyget . Visa hjälpalternativen med hjälpalternativet /? .

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>dbh /?
dbh dbghelp shell
usage: dbh [-n] [-c] [-d] [-?] [-??] [-p] [targetmodule] [command]
       [-n]             display noisy symbol spew
       [-d]             use decorated publics
       [-p:XXXX]        attaches to process ID XXXX
       [-s:SSSS]        set symbol path to SSSS
       [-c]             callbacks return false
       [targetmodule]   load symbols for specified module
       [command]        execute command and exit
       [-?]             display these usage instructions
       [-??]            display detailed usage instructions

Använd ett verktyg som Tlist för att lista process-ID:er och alternativet -p att ansluta till en befintlig process.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>dbh -p:4308

DBH använder samma symbolalternativ som felsökningsprogrammet. Precis som felsökningsprogrammet lämnar DBH SYMOPT_PUBLICS_ONLY och SYMOPT_NO_PUBLICS av som standard och aktiverar SYMOPT_UNDNAME och SYMOPT_AUTO_PUBLICS som standard. Dessa standardvärden kan åsidosättas av ett kommandoradsalternativ eller med ett DBH-kommando.

Här är ett exempel där DBH-kommandotillägget 414fe0 används tre gånger. Första gången används standardsymbolalternativen, så informationen hämtas från privata symboldata. Observera att detta inkluderar information om adressen, storleken och datatypen för funktionen fgets. Därefter används kommandot symopt +4000, vilket gör att DBH ignorerar privata symboldata. När adressen 414fe0 sedan körs igen används den offentliga symboltabellen. Den här gången finns det ingen information om storlek och datatyp för funktionen fgets. Slutligen används kommandot symopt -2, vilket gör att DBH inkluderar dekorationer. När adressen 414fe0 körs för sista gången visas den dekorerade versionen av funktionsnamnet _fgets.

pid:4308 mod:TimeTest[400000]: addr 414fe0

fgets
   name : fgets
   addr :   414fe0
   size : 113
  flags : 0
   type : 7e
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagFunction (5)
  index : 7d

pid:4308 mod:TimeTest[400000]: symopt +4000

Symbol Options: 0x10c13
Symbol Options: 0x14c13

pid:4308 mod:TimeTest[400000]: addr 414fe0

fgets
   name : fgets
   addr :   414fe0
   size : 0
  flags : 0
   type : 0
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagPublicSymbol (a)
  index : 7f

pid:4308 mod:TimeTest[400000]: symopt -2

Symbol Options: 0x14c13
Symbol Options: 0x14c11

pid:4308 mod:TimeTest[400000]: addr 414fe0

_fgets
   name : _fgets
   addr :   414fe0
   size : 0
  flags : 0
   type : 0
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagPublicSymbol (a)
  index : 7f 

Ytterligare information

Mer information om symboler finns i Symbolsyntax och Symbolmatchning, Symbolalternativ, Symbolstatusförkortningar och Uppskjuten symbolinläsning.