Überprüfen von Symbolen
Symbolprobleme können auf verschiedene Arten angezeigt werden. Möglicherweise zeigt eine Stapelablaufverfolgung falsche Informationen an oder identifiziert die Namen der Funktionen im Stapel nicht. Oder vielleicht hat ein Debuggerbefehl den Namen eines Moduls, einer Funktion, einer Variablen, einer Struktur oder eines Datentyps nicht verstanden.
Wenn Sie vermuten, dass der Debugger Symbole nicht ordnungsgemäß lädt, können Sie mehrere Schritte ausführen, um dieses Problem zu untersuchen.
Verwenden Sie zunächst den Befehl lm (List Loaded Modules), um die Liste der geladenen Module mit Symbolinformationen anzuzeigen. Die nützlichste Form dieses Befehls ist die folgende:
0:000> lml
Wenn Sie WinDbg verwenden, wird debug | Mit dem Menübefehl "Module" können Sie auch diese Informationen anzeigen.
Achten Sie besonders auf alle Notizen oder Abkürzungen, die Sie in diesen Anzeigen sehen können. Eine Interpretation dieser Informationen finden Sie unter Abkürzungen für den Symbolstatus.
Wenn die richtigen Symboldateien nicht angezeigt werden, müssen Sie zunächst den Symbolpfad überprüfen:
0:000> .sympath
Current Symbol Path is: d:\MyInstallation\i386\symbols\retail
Wenn der Symbolpfad falsch ist, korrigieren Sie ihn. Wenn Sie den Kerneldebugger verwenden, stellen Sie sicher, dass sich Ihr lokaler %WINDIR% nicht in Ihrem Symbolpfad befindet.
Laden Sie dann symbole mit dem Befehl .reload (Reload Module) neu:
0:000> .reload ModuleName
Wenn Der Symbolpfad korrekt ist, sollten Sie den Lautmodus aktivieren, damit Sie sehen können, welche Symboldateien von dbghelp geladen werden. Laden Sie dann Ihr Modul neu. Informationen zum Aktivieren des lauten Modus finden Sie unter Festlegen von Symboloptionen .
Hier sehen Sie ein Beispiel für ein "lautes" Erneutes Laden der Microsoft Windows-Symbole:
kd> !sym noisy
kd> .reload nt
1: Kernel Version 2081 MP Checked
2: Kernel base = 0x80400000 PsLoadedModuleList = 0x80506fa0
3: DBGHELP: FindExecutableImageEx-> Looking for D:\MyInstallation\i386\ntkrnlmp.exe...mismatched timestamp
4: DBGHELP: No image file available for ntkrnlmp.exe
5: DBGHELP: FindDebugInfoFileEx-> Looking for
6: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.dbg... no file
7: DBGHELP: FindDebugInfoFileEx-> Looking for
8: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.pdb... no file
9: DBGHELP: FindDebugInfoFileEx-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.dbg... OK
10: DBGHELP: LocatePDB-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.pdb... OK
11: *** WARNING: symbols checksum and timestamp is wrong 0x0036a4ea 0x00361a83 for ntkrnlmp.exe
Der Symbolhandler sucht zuerst nach einem Bild, das dem Modul entspricht, das er laden möchte (Zeilen drei und vier). Das Bild selbst ist nicht immer erforderlich, aber wenn ein falsches vorhanden ist, schlägt der Symbolhandler häufig fehl. Diese Zeilen zeigen, dass der Debugger ein Bild bei D:\MyInstallation\i386\ntkrnlmp.exegefunden hat, der Zeit-Datumsstempel jedoch nicht übereinstimmte. Da der Zeitstempel nicht übereinstimmt, wird die Suche fortgesetzt. Als Nächstes sucht der Debugger nach einer DBG-Datei und einer PDB-Datei, die dem geladenen Image entsprechen. Diese befinden sich in den Zeilen 6 bis 10. Zeile 11 gibt an, dass der Zeit-Datumsstempel für das Bild nicht übereinstimmte, obwohl Symbole geladen wurden (d. a. die Symbole waren falsch).
Wenn bei der Symbolsuche ein schwerwiegender Fehler aufgetreten ist, wird eine Meldung des Formulars angezeigt:
ImgHlpFindDebugInfo(00000000, module.dll, c:\MyDir;c:\SomeDir, 0823345, 0) failed
Dies kann durch Elemente wie Dateisystemfehler, Netzwerkfehler und beschädigte DBG-Dateien verursacht werden.
Diagnostizieren von Symbolladefehlern
Im lauten Modus gibt der Debugger möglicherweise Fehlercodes aus, wenn eine Symboldatei nicht geladen werden kann. Die Fehlercodes für DBG-Dateien sind in winerror.h aufgeführt. Die PDB-Fehlercodes stammen aus einer anderen Quelle, und die häufigsten Fehler werden in nur englischem Text ausgegeben.
Einige häufige Fehlercodes für DBG-Dateien von winerror.h sind:
0xB
ERROR_BAD_FORMAT
0x3
ERROR_PATH_NOT_FOUND
0x35
ERROR_BAD_NETPATH
Es ist möglich, dass die Symboldatei aufgrund eines Netzwerkfehlers nicht geladen werden kann. Wenn ERROR_BAD_FORMAT oder ERROR_BAD_NETPATH angezeigt wird und Sie Symbole von einem anderen Computer im Netzwerk laden, versuchen Sie, die Symboldatei auf Ihren Hostcomputer zu kopieren, und fügen Sie deren Pfad in Den Symbolpfad ein. Versuchen Sie dann, die Symbole erneut zu laden.
Überprüfen des Suchpfads und der Symbole
Lassen Sie "c:\MyDir; c:\SomeDir" stellen Ihren Symbolpfad dar. Wo sollten Sie nach Debuginformationen suchen?
In Fällen, in denen der Binärdatei Debuginformationen entfernt wurden, z. B. die kostenlosen Builds von Windows, suchen Sie zuerst nach einer DBG-Datei an den folgenden Speicherorten:
c:\MyDir\symbols\exe\ntoskrnl.dbg
c:\SomeDir\symbols\exe\ntoskrnl.dbg
c:\MyDir\exe\ntoskrnl.dbg
c:\SomeDir\exe\ntoskrnl.dbg
c:\MyDir\ntoskrnl.dbg
c:\SomeDir\ntoskrnl.dbg
current-working-directory\ntoskrnl.dbg
Suchen Sie als Nächstes nach einer PDB-Datei an den folgenden Speicherorten:
c:\MyDir\symbols\exe\ntoskrnl.pdb
c:\MyDir\exe\ntoskrnl.pdb
c:\MyDir\ntoskrnl.pdb
c:\SomeDir\symbols\exe\ntoskrnl.pdb
c:\SomeDir\exe\ntoskrnl.pdb
c:\SomeDir\ntoskrnl.pdb
current-working-directory\ntoskrnl.pdb
Beachten Sie, dass der Debugger bei der Suche nach der DBG-Datei interleasiert und die Verzeichnisse MyDir und SomeDir durchsucht, in der PDB-Suche jedoch nicht.
Windows XP und höhere Versionen von Windows verwenden keine .dbg-Symboldateien. Weitere Informationen finden Sie unter Symbole und Symboldateien .
Nicht übereinstimmende Builds
Eines der häufigsten Probleme beim Debuggen von Fehlern auf einem Computer, der häufig aktualisiert wird, sind nicht übereinstimmende Symbole aus verschiedenen Builds. Drei häufige Ursachen für dieses Problem sind: Das Zeigen auf Symbole für den falschen Build, die Verwendung einer privat erstellten Binärdatei ohne die entsprechenden Symbole und die Verwendung der Uniprozessor-Hardwareabstraktionsebene (HAL) und Kernelsymbole auf einem Multiprozessorcomputer. Die ersten beiden sind einfach eine Frage des Abgleichs Ihrer Binärdateien und Symbole; die dritte kann korrigiert werden, indem Sie Ihre hal*.dbg und ntkrnlmp.dbg in hal.dbg und ntoskrnl.dbg umbenennen.
Um herauszufinden, welcher Build von Windows auf dem Zielcomputer installiert ist, verwenden Sie den Befehl vertarget (Zielcomputerversion anzeigen):
kd> vertarget
Windows XP Kernel Version 2505 UP Free x86 compatible
Built by: 2505.main.010626-1514
Kernel base = 0x804d0000 PsLoadedModuleList = 0x80548748
Debug session time: Mon Jul 02 14:41:11 2001
System Uptime: 0 days 0:04:53
Testen der Symbole
Das Testen der Symbole ist schwieriger. Dabei wird eine Stapelüberwachung im Debugger überprüft und überprüft, ob die Debugausgabe korrekt ist. Hier sehen Sie ein Beispiel, das Sie ausprobieren können:
kd> u videoprt!videoportfindadapter2
Loading symbols for 0xf2860000 videoprt.sys -> videoprt.sys
VIDEOPRT!VideoPortFindAdapter2:
f2856f42 55 push ebp
f2856f43 8bec mov ebp,esp
f2856f45 81ecb8010000 sub esp,0x1b8
f2856f4b 8b4518 mov eax,[ebp+0x18]
f2856f4e 53 push ebx
f2856f4f 8365f400 and dword ptr [ebp-0xc],0x
f2856f53 8065ff00 and byte ptr [ebp-0x1],0x0
f2856f57 56 push esi
Der Befehl u hebt die Zeichenfolge videoportfindadapter in videoprt.sys auf. Die Symbole sind im Debugger korrekt, da allgemeine Stapelbefehle wie push und mov auf dem Stapel angezeigt werden. Die meisten Funktionen beginnen mit einem Add-, Sub- oder Pushvorgang, der entweder den Basiszeiger (ebp) oder den Stapelzeiger (esp) verwendet.
Dies ist in der Regel offensichtlich, wenn die Symbole nicht ordnungsgemäß funktionieren. Glintmp.sys enthält in diesem Beispiel keine Symbole, da neben Glintmp keine Funktion aufgeführt ist:
kd> kb
Loading symbols for 0xf28d0000 videoprt.sys -> videoprt.sys
Loading symbols for 0xf9cdd000 glintmp.sys -> glintmp.sys
*** ERROR: Symbols could not be loaded for glintmp.sys
ChildEBP RetAddr Args to Child
f29bf1b0 8045b5fa 00000001 0000a100 00000030 ntoskrnl!RtlpBreakWithStatusInstruction
f29bf1b0 8044904e 00000001 0000a100 00000030 ntoskrnl!KeUpdateSystemTime+0x13e
f29bf234 f28d1955 f9b7d000 ffafb2dc f9b7d000 ntoskrnl!READ_REGISTER_ULONG+0x6
f29bf248 f9cde411 f9b7d000 f29bf2b0 f9ba0060 VIDEOPRT!VideoPortReadRegisterUlong+0x27
00000002 00000000 00000000 00000000 00000000 glintMP+0x1411 [No function listed.]
Für diese Stapelüberwachung wurden die falschen Buildsymbole geladen. Beachten Sie, dass für die ersten beiden Aufrufe keine Funktionen aufgeführt sind. Diese Stapelüberwachung sieht wie ein Problem mit win32k.sys Zeichnungsrechtecke aus:
1: kd>
1: kd> kb [Local 9:50 AM]
Loading symbols for 0xf22b0000 agpcpq.sys -> agpcpq.sys
*** WARNING: symbols checksum is wrong 0x0000735a 0x00000000 for agpcpq.sys
*** ERROR: Symbols could not be loaded for agpcpq.sys
Loading symbols for 0xa0000000 win32k.sys -> win32k.sys
*** WARNING: symbols checksum is wrong 0x00191a41 0x001995a9 for win32k.sys
ChildEBP RetAddr Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ+0x125b [No function listed.]
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 agpCPQ+0x372b [No function listed.]
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!vPatCpyRect1_6x6+0x20b
00000001 00000000 00000000 00000000 00000000 win32k!RemoteRedrawRectangle+0x32
Hier ist die richtige Stapelüberwachung. Das Problem ist wirklich mit AGP440.sys. Das erste Element, das in einer Stapelüberwachung angezeigt wird, ist in der Regel fehlerhaft. Beachten Sie, dass der win32k.sys Rechteckfehler nicht mehr vorhanden ist:
1: kd> kb [Local 9:49 AM]
ChildEBP RetAddr Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ!AgpReleaseMemory+0x88
be682b30 f20a385c 82703638 e183ec68 00000000 agpCPQ!AgpInterfaceReleaseMemory+0x8b
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 VIDEOPRT!AgpReleasePhysical+0x44
be682b58 a0139605 e1cee560 e11410a8 a00e5f0a win32k!OsAGPFree+0x14
be682b64 a00e5f0a e1cee560 e11410a8 e1cee560 win32k!AGPFree+0xd
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!HeapVidMemFini+0x49
be682b9c a00f5c20 e1cee008 e1cee008 be682c0c win32k!vDdDisableDriver+0x3a
be682bac a00da510 e1cee008 00000000 be682c0c win32k!vDdDisableDirectDraw+0x2d
be682bc4 a00da787 00000000 e1843df8 e1843de8 win32k!PDEVOBJ__vDisableSurface+0x27
be682bec a00d59fb 00000000 e1843de8 00000000 win32k!PDEVOBJ__vUnreferencePdev+0x204
be682c04 a00d7421 e1cee008 82566a98 00000001 win32k!DrvDestroyMDEV+0x30
be682ce0 a00a9e7f e1843e10 e184a008 00000000 win32k!DrvChangeDisplaySettings+0x8b3
be682d20 a008b543 00000000 00000000 00000000 win32k!xxxUserChangeDisplaySettings+0x106
be682d48 8045d119 00000000 00000000 00000000 win32k!NtUserChangeDisplaySettings+0x48
be682d48 77e63660 00000000 00000000 00000000 ntkrnlmp!KiSystemService+0xc9
Nützliche Befehle und Erweiterungen
Die folgenden Befehle und Erweiterungen können nützlich sein, um Symbolprobleme nachzuverfolgen:
lm (Geladene Module auflisten)
Listet alle Module auf und gibt die status aller Symbole in diesen Modulen an.
!dh image-header-base
Zeigt Kopfzeileninformationen für ein geladenes Bild an, beginnend bei image-header-base.
.reload /n
Lädt alle Kernelsymbole neu.
.reload [image-name]
(nur CDB oder WinDbg) Lädt Symbole für den Imagenamen erneut. Wenn kein Imagename angegeben ist, werden Symbole für alle Bilder neu geladen. (Es ist erforderlich, Symbole neu zu laden, nachdem der Symbolpfad geändert wurde.)
!sym noisy
Aktiviert den ausführlichen Modus für das Laden von Symbolen. Dies kann verwendet werden, um Informationen zu den Modulladevorgängen abzurufen. Weitere Informationen finden Sie unter Festlegen von Symboloptionen .
.sympath [new-symbol-path]
Legt einen neuen Symbolpfad fest oder zeigt den aktuellen Symbolpfad an. Weitere Informationen finden Sie unter Symbolpfad .
Wenn die Kernelsymbole korrekt sind, Sie aber keinen vollständigen Stapel erhalten, können die folgenden Befehle ebenfalls nützlich sein:
X*!
Dadurch werden die Module aufgelistet, die derzeit über geladene Symbole verfügen. Dies ist nützlich, wenn die Kernelsymbole korrekt sind.
.reload /user
Dadurch wird versucht, alle Benutzermodussymbole neu zu laden. Dies ist beim Debuggen des Kernels erforderlich, wenn Symbole geladen wurden, während ein Prozess ausgeführt wurde, und später ein Break in einem anderen Prozess aufgetreten ist. In diesem Fall werden die Benutzermodussymbole aus dem neuen Prozess nur geladen, wenn dieser Befehl ausgeführt wird.
X wdmaud!*start\*
Dadurch werden nur die Symbole im wdmaud-Modul aufgelistet, deren Namen die Startzeichenfolge enthalten. Dies hat den Vorteil, dass es das Neuladen aller Symbole in wdmaud erzwingt, aber nur diejenigen mit "Start" anzeigt. (Dies bedeutet eine kürzere Auflistung, aber da immer einige Symbole mit "Start" enthalten sind, wird überprüft, ob die Last stattgefunden hat.)
Eine weitere nützliche Technik zum Überprüfen von Symbolen ist das Aufheben des Zusammenbaus von Code. Die meisten Funktionen beginnen mit einem Add-, Sub- oder Pushvorgang, der entweder den Basiszeiger (ebp) oder den Stapelzeiger (esp oder sp) verwendet. Versuchen Sie, einige Funktionen auf dem Stapel (von Offset Null) aufzuheben (U-Funktion), um die Symbole zu überprüfen.
Netzwerk- und Portprobleme
Probleme treten mit den Symboldateien und beim Herstellen einer Verbindung mit dem Debugger auf. Im Folgenden finden Sie einige Punkte, die Sie beachten sollten, wenn Sie Probleme haben:
Bestimmen Sie, mit welchem COM-Port das Debugkabel auf dem Testsystem verbunden ist.
Überprüfen Sie die boot.ini Einstellungen des Testsystems. Suchen Sie nach dem Schalter /debug , und überprüfen Sie die Einstellungen für baudrate und COM-Port.
Netzwerkprobleme können das Debuggen beeinträchtigen, wenn über das Netzwerk auf die Symboldateien zugegriffen wird.
.dll und .sys Dateien mit demselben Namen (z. B. − mga64.sys und mga64.dll) verwirren den Debugger, wenn sie nicht in die richtigen Verzeichnisse der Symbolstruktur unterteilt sind.
Der Kerneldebugger mag es nicht immer, die Buildsymboldateien durch private Symboldateien zu ersetzen. Überprüfen Sie den Symbolpfad, und führen Sie einen .reloadFileName für das falsch angezeigte Symbol aus. Der Befehl !dlls ist manchmal nützlich.
Fragen und Missverständnisse
Q: Ich habe Symbole erfolgreich geladen, aber der Stapel scheint falsch zu sein. Ist der Debugger defekt?
Eine: Nicht unbedingt. Die wahrscheinlichste Ursache für Ihr Problem ist, dass Sie falsche Symbole haben. Gehen Sie die in diesem Abschnitt beschriebenen Schritte durch, um zu ermitteln, ob Sie gültige Symbole geladen haben oder nicht. Gehen Sie nicht davon aus, dass Sie gültige Symbole haben, da einige Dinge funktionieren. Beispielsweise können Sie sehr gut dd nt!nt!ntbuildnumber oder u nt! KeInitializeProcess mit falschen Symbolen. Vergewissern Sie sich, dass sie richtig sind, indem Sie die oben beschriebenen Prozeduren verwenden.
Q: Funktioniert der Debugger weiterhin mit falschen Symbolen?
Eine: Ja und nein. Häufig können Sie mit Symbolen durchkommen, die nicht genau übereinstimmen. Beispielsweise funktionieren Symbole aus einem früheren Windows-Build häufig in bestimmten Fällen, aber es gibt keine Regel, wann dies funktioniert und wann nicht.
Q: Ich bin im Kerneldebugger angehalten und möchte Symbole für meinen Benutzermodusprozess anzeigen. Kann ich das tun?
Eine: Meist. Die Unterstützung für dieses Szenario ist schlecht, da der Kerneldebugger nicht genügend Informationen enthält, um die Modulladungen für jeden Prozess nachzuverfolgen, aber es gibt eine vernünftige Problemumgehung. Um Symbole für ein Benutzermodusmodul zu laden, führen Sie den Befehl .reload -user aus. Dadurch werden die Benutzermodusmodule für den aktuellen Kontext geladen.
Q: Was bedeutet die folgende Meldung?
*** WARNING: symbols checksum and timestamp is wrong 0x0036d6bf 0x0036ab55 for ntkrnlmp.exe
Eine: Dies bedeutet, dass Ihre Symbole für ntkrnlmp.exe falsch sind.