Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Installatie en configuratie van de debugger
Sommige acties voor toepassingsverificator kunnen ertoe leiden dat er een uitzondering wordt gegenereerd. Het foutopsporingsprogramma moet worden ingesteld om deze uitzonderingen op de tweede kans te ondervangen, omdat Application Verifier zelf de eerste kansuitzondering afhandelt.
De rijzende uitzonderingen zijn van drie typen:
Er wordt een uitzondering voor toegangsschending (0xC0000005) gegenereerd als met de heap-optie een heapbufferoverschrijding wordt gedetecteerd. In sommige gevallen kan de optie Systeempadgebruik controleren ook een schending van de toegang veroorzaken.
Er wordt een ongeldige handle-uitzondering (0xC0000008) gegenereerd wanneer de optie Ongeldig ingangsgebruik detecteren een ongeldige ingangsbewerking detecteert.
Er wordt een uitzondering voor stackoverloop (0xC00000FD) gegenereerd wanneer de optie Controleren op voldoende stack detecteert dat de eerste stack te kort was.
Een manier om deze gebeurtenissen voor te bereiden, is door het foutopsporingsprogramma op een opdrachtregel als volgt te starten:
windbg -xd av -xd ch -xd sov ApplicationCommandLine
or
cdb -xd av -xd ch -xd sov ApplicationCommandLine
Als u het foutopsporingsprogramma al hebt gestart, kunt u de opdracht sxd (Uitzonderingen instellen) gebruiken om alle toegangsschendingen, ongeldige ingangen en stack-overloop te ondervangen als uitzonderingen voor de tweede kans:
0:000> sxd av
0:000> sxd ch
0:000> sxd sov 1
Het is theoretisch mogelijk om Application Verifier te beheren via een kernelfoutopsporingsprogramma. Dit wordt echter niet aanbevolen. Het vereist regelmatig gebruik van de .process- en .pagein-opdrachten, maar het biedt u niet meer mogelijkheden dan het gebruik van een foutopsporingsprogramma in de gebruikersmodus.
De hulpprogramma's voor foutopsporing installeren
Als u de nieuwste versie van de hulpprogramma's wilt downloaden, raadpleegt u Hulpprogramma's voor foutopsporing voor Windows downloaden.
Hardware configureren voor User-Mode foutopsporing
Foutopsporing in de gebruikersmodus wordt over het algemeen uitgevoerd op één computer: het foutopsporingsprogramma wordt uitgevoerd op dezelfde computer als de toepassing die is mislukt.
In dit geval is er geen specifieke hardware-installatie vereist. In dit onderwerp zijn de termen hostcomputer en doelcomputer in dit geval uitwisselbaar.
Software configureren voor User-Mode foutopsporing
Basic User-Mode-configuratie: voordat u foutopsporing in de gebruikersmodus kunt starten, moet u de benodigde symboolbestanden downloaden en bepaalde omgevingsvariabelen instellen.
Symboolbestanden
U moet de symboolbestanden downloaden voor het gebruikersmodusproces dat wordt gedebugd. Als dit een toepassing is die u hebt geschreven, moet deze worden gebouwd met volledige symboolbestanden. Als het een commerciële toepassing is, zijn de symboolbestanden mogelijk beschikbaar op een webserver of voor downloaden, neem dan contact op met de fabrikant.
als u externe foutopsporing uitvoert, is de locatie van het symboolbestand afhankelijk van de methode die u gebruikt:
Als u externe foutopsporing uitvoert via het foutopsporingsprogramma, moeten de symboolbestanden zich op de computer bevinden met de foutopsporingsserver.
Als u externe foutopsporing uitvoert via remote.exe, moeten de symboolbestanden zich op de computer bevinden met het foutopsporingsprogramma.
Als u externe foutopsporing uitvoert via een processerver of een KD-verbindingsserver, moeten de symboolbestanden zich op de computer met de slimme client bevinden.
Als u het foutopsporingsprogramma voor de gebruikersmodus beheert vanuit het kernelfoutopsporingsprogramma, moeten de symboolbestanden zich op beide computers bevinden.
Omgevingsvariabelen configureren
Het foutopsporingsprogramma maakt gebruik van verschillende omgevingsvariabelen om een aantal belangrijke instellingen aan te geven.
Zie Aan de slag met Windows-foutopsporing voor meer informatie over foutopsporingsprogramma's
Toepassingsverificator configureren met het foutopsporingsprogramma met behulp van de opdrachtregel
Als u Toepassingsverifier wilt configureren, kunt u de CDB- of NTSD-opdrachtregel gebruiken.
Gebruik de volgende opdrachtregel:
cdb OtherOptions -vf:Flags Target
Waarbij Target de naam van de doeltoepassing is en vlaggen de gewenste opties voor toepassingsverificator opgeven die op dit doel moeten worden toegepast.
Vlaggen moeten een som zijn van de bits die de gewenste opties vertegenwoordigen. De afzonderlijke bitwaarden zijn als volgt:
| Vlagwaarde | Betekenis |
|---|---|
| 00000001 | HEAP-CONTROLES |
| 00000004 | CONTROLES VERWERKEN |
| 00000008 | CONTROLES VAN SIM-KAARTEN MET WEINIG RESOURCES |
| 00000020 | TLS CONTROLES |
| 00000040 | VUILE STAPELS |
| 00000200 | GEVAARLIJKE API'S |
| 00001000 | UITZONDERINGSCONTROLES |
| 00002000 | GEHEUGENCONTROLES |
| 00020000 | DIVERSE CONTROLES |
| 00040000 | VERGRENDELINGSCONTROLES |
Foutopsporing met !avrf
De extensie !avrf bepaalt de instellingen van Application Verifier en geeft een verscheidenheid aan uitvoer weer die wordt geproduceerd door Application Verifier. Zie !avrf in de documentatie voor foutopsporing voor meer informatie over de extensie !arvrf.
Syntaxis
!avrf
Met de opdracht !avrf zonder parameters worden de instellingen van de Application Verifier en informatie over de huidige en eventuele eerdere onderbrekingen van de Application Verifier weergegeven, indien aanwezig.
!avrf –vs { Length | -aAddress }
Geeft het bewerkingslogboek van de virtuele ruimte weer. Lengte geeft het aantal records op dat moet worden weergegeven vanaf de meest recente. Het adres geeft het virtuele adres op. Records van de virtuele bewerkingen die dit virtuele adres bevatten, worden weergegeven.
!avrf -hp { Length | -a Address }
Geeft het heap-bewerkingslogboek weer. Adres geeft het heap-adres op. Records van de heap-bewerkingen met dit heap-adres worden weergegeven.
!avrf -cs { Length | -a Address }
Geeft het logboek voor het verwijderen van kritieke secties weer. Lengte geeft het aantal records op dat moet worden weergegeven vanaf de meest recente. Adres geeft het adres van de kritieke sectie op. Records voor de specifieke kritieke sectie worden weergegeven wanneer Adres is opgegeven.
!avrf -dlls [ Length ]
Geeft het DLL-logboek voor laden/uitladen weer. Lengte geeft het aantal records op dat moet worden weergegeven vanaf de meest recente.
!avrf -trm
Geeft een logboek weer van alle beëindigde en onderbroken threads.
!avrf -ex [ Length ]
Geeft het uitzonderingslogboek weer. Toepassingsverificator houdt alle uitzonderingen bij die plaatsvinden in de toepassing.
!avrf -threads [ ThreadID ]
Geeft informatie weer over threads in het doelproces. Voor kinderthreads worden ook de stackgrootte en de door de bovenliggende thread opgegeven CreateThread-vlaggen weergegeven. Als u een thread-id opgeeft, wordt alleen informatie voor die specifieke thread weergegeven.
!avrf -tp [ ThreadID ]
Geeft het logboek van de threadgroep weer. Dit logboek kan stacktraceringen bevatten voor verschillende bewerkingen, zoals het wijzigen van het threadaffiniteitsmasker, het wijzigen van threadprioriteit, het plaatsen van threadberichten, het initialiseren van COM en het niet-initialiseren van COM vanuit de callback van de threadpool. Als u een thread-id opgeeft, wordt alleen informatie voor die specifieke thread weergegeven.
!avrf -srw [ Address | Address Length ] [ -stats ]
Geeft het SRW-logboek (Slim Reader/Writer) weer. Als u een adres specificeert, worden records met betrekking tot het betreffende SRW-slotadres weergegeven. Wanneer lengte wordt opgegeven samen met het adres, worden alle SRW-vergrendelingen binnen dat adresbereik weergegeven. De -stats-optie dumpt de statistieken van de SRW-vergrendeling.
!avrf -leak [ -m ModuleName ] [ -r ResourceType ] [ -a Address ] [ -t ]
Geeft het uitstaande middelenlogboek weer. Deze resources kunnen op elk willekeurig moment al dan niet lekken. Als u ModuleName (inclusief de extensie) opgeeft, worden alle openstaande resources in de opgegeven module weergegeven. Als u ResourceType opgeeft, worden openstaande resources van dat specifieke resourcetype weergegeven. Het specificeren van een adres dumpt records van openstaande resources met dat adres. ResourceType kan een van de volgende zijn:
- Heap: Geeft heap-toewijzingen weer met behulp van Win32 Heap-API's
- Lokaal: Lokale/globale toewijzingen weergeven
- CRT: Toewijzingen weergeven met CRT-APIs
- Virtueel: Virtuele reserveringen weergeven
- BSTR: Geeft BSTR-toewijzingen weer
- Register: Registersleutel wordt geopend
- Energie: Geeft energiemeldingsobjecten weer
- Handle: Weergave van handle-toewijzingen voor threads, bestanden en gebeurtenissen
!avrf –trace TraceIndex
Geeft een stacktracering weer voor de opgegeven traceringsindex. Sommige structuren gebruiken dit 16-bits indexnummer om een stacktracering te identificeren. Deze index verwijst naar een locatie in de stack trace-database. Als u een dergelijke structuur analyseert, vindt u deze syntaxis nuttig.
!avrf -cnt
Geeft een lijst met globale tellers weer.
!avrf -brk [ BreakEventType ]
Hiermee geeft u op dat dit een onderbrekingsgebeurtenisopdracht is. Wanneer !avrf -brk wordt gebruikt zonder extra parameters, worden de instellingen voor onderbrekingsevenementen weergegeven. BreakEventType geeft het typenummer van de break-gebeurtenis op. Gebruik !avrf -brkvoor een lijst met mogelijke typen .
!avrf -flt [ EventTypeProbability ]
Hiermee geeft u aan dat dit een foutinjectiecommando is. Wanneer !avrf -flt wordt gebruikt zonder extra parameters, worden de huidige instellingen voor foutinjectie weergegeven. EventType geeft het type nummer van de gebeurtenis op. De kans geeft de frequentie aan waarmee de gebeurtenis mislukt. Dit kan een geheel getal zijn tussen 0 en 1.000.000 (0xF4240).
!avrf -flt break EventType
Zorgt ervoor dat Application Verifier inbreekt in het foutopsporingsprogramma telkens wanneer deze fout wordt geïnjecteerd.
!avrf -flt stacks Length
Geeft het 'Length' aantal stacktraceringen weer voor de meest recente fout-geïnjecteerde bewerkingen.
!avrf -trg [ StartEnd | dll Module | all ]
Hiermee geeft u op dat dit een doelbereikopdracht is. Wanneer -trg zonder extra parameters wordt gebruikt, worden de huidige doelbereiken weergegeven. Start geeft het beginadres van het doelbereik of uitsluitingsbereik op. Einde geeft het eindadres van het doelbereik of uitsluitingsbereik op. Module geeft de naam op van een module die moet worden gericht of uitgesloten. Module moet de volledige modulenaam bevatten, inclusief de .exe of .dll extensie. Padinformatie mag niet worden opgenomen. Als u alles specificeert, worden alle doelbereiken of uitsluitingsbereiken opnieuw ingesteld.
!avrf -skp [ StartEnd | dll Module | all | Time ]
Hiermee geeft u op dat dit een uitsluitingsbereikopdracht is. Start geeft het beginadres van het doelbereik of uitsluitingsbereik op. Einde geeft het eindadres van het doelbereik of uitsluitingsbereik op. Module geeft de naam op van een module die moet worden gericht of uitgesloten. Module moet de volledige modulenaam bevatten, inclusief de .exe of .dll extensie. Padinformatie mag niet worden opgenomen. Wanneer u alles specificeert, worden alle doelbereiken of uitsluitingsbereiken opnieuw ingesteld. Door tijd op te geven, worden alle fouten onderdrukt voor tijd milliseconden nadat de uitvoering is hervat.
Hieronder ziet u de uitvoer van de opdracht !avrf in het foutopsporingsprogramma.
0:000> !avrf
Application verifier settings (816431A7):
- full page heap
- COM
- RPC
- Handles
- Locks
- Memory
- TLS
- Exceptions
- Threadpool
- Leak
- SRWLock
No verifier stop active.
Note: Sometimes bugs found by verifier manifest themselves as raised
exceptions (access violations, stack overflows, invalid handles),
and it is not always necessary to have a verifier stop.
!avrf extensie opmerkingen
Wanneer de !avrf-extensie zonder parameters wordt gebruikt, worden de huidige opties voor toepassingsverificator weergegeven.
De extensie !avrf maakt gebruik van de Exts.dll in het foutopsporingsprogramma.
Als er een Stop van toepassingsverificator is opgetreden, zal de !avrf-extensie zonder parameters de aard van de stop en de oorzaak ervan onthullen.
Als symbolen voor ntdll.dll en verifier.dll ontbreken, genereert de extensie !avrf een foutbericht.
Doorlopende en niet-doorlopende onderbrekingen
Foutopsporing van een continue stop
Hier is een voorbeeld van een ongeldige handvat-uitzondering die is gegenereerd door de optie Ongeldig handvatgebruik detecteren.
Eerst wordt het volgende bericht weergegeven:
Invalid handle - code c0000008 (first chance)
===================================================
VERIFIER STOP 00000300: pid 0x558: invalid handle exception for current stack trace
C0000008 : Exception code.
0012FBF8 : Exception record. Use .exr to display it.
0012FC0C : Context record. Use .cxr to display it.
00000000 :
===================================================
This verifier stop is continuable.
After debugging it use 'go' to continue.
===================================================
Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=6a27c280 ecx=6a226447 edx=0012fa4c esi=00942528 edi=6a27c260
eip=6a22629c esp=0012facc ebp=0012faf0 iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!DbgBreakPoint:
6a22629c cc int 3
U ziet dat het bericht u vertelt dat deze toepassingsverificatorstop kan worden voortgezet. Nadat u weet wat er is gebeurd, kunt u doorgaan met het uitvoeren van de doeltoepassing.
Gebruik eerst de !avrf extensie. Dit geeft informatie over de huidige fout:
0:000> !avrf
Global flags: 00000100
Application verifier global flag is set.
Application verifier settings (00000004):
- no heap checking enabled!
- handle checks
Page heap is not active for this process.
Current stop 00000300 : c0000008 0012fbf8 0012fc0c 00000000 .
Using an invalid handle (either closed or simply bad).
De laatste regel van deze weergave geeft een overzicht van het probleem.
U kunt op dit moment enkele logboeken bekijken. Nadat u klaar bent, gebruikt u de opdracht g (Go) om de toepassing opnieuw te starten:
0:000> g
## Debugging a Non-Continuable Stop
Here is an example of an access violation that has been raised by the page heap option.
First, the following message appears:
Access violation - code c0000005 (first chance)
===================================================
VERIFIER STOP 00000008: pid 0x504: exception raised while verifying block header
00EC1000 : Heap handle
00F10FF8 : Heap block
00000000 : Block size
00000000 :
===================================================
This verifier stop is not continuable. Process will be terminated when you use the 'go' debugger command.
===================================================
Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=6a226447 edx=0012fab7 esi=00f10ff8 edi=00000008
eip=6a22629c esp=0012fb5c ebp=0012fb80 iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!DbgBreakPoint:
6a22629c cc int 3
In dit geval wordt in het bericht aangegeven dat deze toepassingsverificatorstop niet kan worden voortgezet. De fout is te ernstig voor het uitvoeren van het proces en er is geen manier voor Application Verifier om het proces te redden.
De !avrf-extensie kan worden gebruikt om informatie te geven over de huidige fout:
0:000> !avrf
Global flags: 02000100
Application verifier global flag is set.
Page heap global flag is set.
Application verifier settings (00000001):
- full page heap
Page heaps active in the process (format: pageheap, lightheap, flags):
00941000 , 00a40000 , 3 (pageheap traces )
00b41000 , 00c40000 , 3 (pageheap traces )
00cb1000 , 00db0000 , 3 (pageheap traces )
00ec1000 , 00fc0000 , 3 (pageheap traces )
Current stop 00000008 : 00ec1000 00f10ff8 00000000 00000000 .
Corrupted heap block.
De laatste regel van deze weergave geeft een overzicht van het probleem.
Mogelijk wilt u op dit moment ook enkele logboeken bekijken. U kunt de opdracht .restart (Doeltoepassing opnieuw opstarten) op dit moment gebruiken. Of misschien wilt u de sessie voor toepassingsverificator beëindigen en beginnen met het oplossen van de fouten in uw code.
Debuggen van kritieke sectiefouten
!cs foutopsporingsprogramma-extensie
!cs kan worden gebruikt in zowel foutopsporingsprogramma in de gebruikersmodus als kernelfoutopsporingsprogramma om informatie weer te geven over kritieke secties in het huidige proces. Zie !cs in de foutopsporingsprogrammadocumenten voor meer informatie over de extensie !cs .
Overeenkomende symbolen met typegegevens zijn vereist, met name voor ntdll.dll.
De syntaxis voor deze extensie is:
!cs [-s] - dump alle actieve kritieke secties in het huidige proces.
!cs [-s] adres - dumpen kritieke sectie op het opgegeven adres.
!cs [-s] -d adres - dump kritieke sectie die overeenkomt met DebugInfo op dit adres.
-s dumpt de initialisatiestack-trace van het kritieke codeblok als deze beschikbaar is.
Voorbeelden:
Dumpinformatie over een kritieke sectie met behulp van het adres
0:001> ! cs 0x7803B0F8
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
DebugInfo = 0x6A262080
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Dump informatie over een kritieke sectie met behulp van het adres, inclusief initialisatiestacktrace
0:001> !cs -s 0x7803B0F8
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
DebugInfo = 0x6A262080
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Stack trace for DebugInfo = 0x6A262080:
0x6A2137BD: ntdll!RtlInitializeCriticalSectionAndSpinCount+0x9B
0x6A207A4C: ntdll!LdrpCallInitRoutine+0x14
0x6A205569: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DCE1: ntdll!LdrpInitializeProcess+0xAE5
Dump informatie over een kritieke sectie met behulp van het adres van de foutopsporingsgegevens
0:001> !cs -d 0x6A262080
DebugInfo = 0x6A262080
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Geef informatie weer over een kritische sectie met behulp van het adres van de foutopsporingsgegevens, inclusief initialisatie-stack-trace
0:001> !cs -s -d 0x6A262080
DebugInfo = 0x6A262080
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Stack trace for DebugInfo = 0x6A262080:
0x6A2137BD: ntdll!RtlInitializeCriticalSectionAndSpinCount+0x9B
0x6A207A4C: ntdll!LdrpCallInitRoutine+0x14
0x6A205569: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DCE1: ntdll!LdrpInitializeProcess+0xAE
Dumpinformatie over alle actieve kritieke secties in het huidige proces
0:001> !cs
-----------------------------------------
DebugInfo = 0x6A261D60
Critical section = 0x6A262820 (ntdll!RtlCriticalSectionLock+0x0)
LOCKED
LockCount = 0x0
OwningThread = 0x460
RecursionCount = 0x1
LockSemaphore = 0x0
SpinCount = 0x0
-----------------------------------------
DebugInfo = 0x6A261D80
Critical section = 0x6A262580 (ntdll!DeferedCriticalSection+0x0)
NOT LOCKED
LockSemaphore = 0x7FC
SpinCount = 0x0
-----------------------------------------
DebugInfo = 0x6A262600
Critical section = 0x6A26074C (ntdll!LoaderLock+0x0)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
.....
Geef informatie weer over alle actieve kritieke secties in het huidige proces, inclusief initialisatiestacktrace.
0:001> !cs -s
...
-----------------------------------------
DebugInfo = 0x6A261EA0
Critical section = 0xA8001C (+0xA8001C)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
No stack trace saved
-----------------------------------------
DebugInfo = 0x6A261EC0
Critical section = 0x6A263560 (ntdll!RtlpDphTargetDllsLock+0x0)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
No stack trace saved
-----------------------------------------
DebugInfo = 0x6A261EE0
Critical section = 0xA90608 (+0xA90608)
NOT LOCKED
LockSemaphore = 0x7EC
SpinCount = 0x0
Stack trace for DebugInfo = 0x6A261EE0:
0x6A2137BD: ntdll!RtlInitializeCriticalSectionAndSpinCount+0x9B
0x6A20B0DC: ntdll!CsrpConnectToServer+0x1BE
0x6A20B2AA: ntdll!CsrClientConnectToServer+0x148
0x77DBE83F: KERNEL32!BaseDllInitialize+0x11F
0x6A207A4C: ntdll!LdrpCallInitRoutine+0x14
0x6A205569: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DCE1: ntdll!LdrpInitializeProcess+0xAE5
-----------------------------------------
DebugInfo = 0x6A261F00
Critical section = 0x77E1AEB8 (KERNEL32!BaseDllRegistryCache+0x18)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Stack trace for DebugInfo = 0x6A261F00:
0x6A2137BD: ntdll!RtlInitializeCriticalSectionAndSpinCount+0x9B
0x6A207A4C: ntdll!LdrpCallInitRoutine+0x14
0x6A205569: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DCE1: ntdll!LdrpInitializeProcess+0xAE5
Foutopsporing van uitzonderingen
In het uitzonderingslogboek worden alle uitzonderingen vastgelegd die zijn opgetreden in het doelproces.
U kunt de opdracht !avrf -ex Length extension gebruiken om de laatste uitzonderingen weer te geven; Lengte geeft het aantal uitzonderingen op. Als lengte wordt weggelaten, worden alle uitzonderingen weergegeven.
Hier volgt een voorbeeld:
0:000> !avrf -ex 4
=================================
Thread ID: 0000052c
Exception code: c0000008
Exception address: 6a226663
Exception record: 0012fb50
Context record: 0012fb64
Displayed 1 exception log entries.
Debuggen handelt fouten af
!htrace kan worden gebruikt in zowel gebruikersmodus-debugger als kernel-debugger om stack-trace-informatie voor een of alle handles in een proces weer te geven. Deze informatie is beschikbaar als tracering van handles is ingeschakeld voor het proces, automatisch ingeschakeld als handlecontrole is ingeschakeld in de toepassingsverificator. Stack-traceringen worden opgeslagen telkens wanneer het proces een ingang opent of sluit of wanneer er naar een ongeldige ingang wordt verwezen. Zie !htrace in de documentatie voor foutopsporing voor meer informatie over de extensie !htrace .
De syntaxis van het kernelfoutopsporingsprogramma voor deze extensie is:
!htrace [ handle [process] ]
Als de ingang niet is opgegeven of 0 is, wordt informatie over alle ingangen in het proces weergegeven. Als het proces niet is opgegeven, wordt het huidige proces gebruikt.
De syntaxis van het foutopsporingsprogramma in de gebruikersmodus is:
!htrace [handle]
De extensie voor foutopsporingsprogramma in de gebruikersmodus geeft altijd informatie weer over het huidige foutopsporingsproces.
Voorbeelden:
Dumper informatie over handle 7CC in proces 815328b0
kd> !htrace 7CC 815328b0
Loaded \\...\kdexts extension DLL
Process 0x815328B0
ObjectTable 0xE15ECBB8
--------------------------------------
Handle 0x7CC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x77DBFCD6: KERNEL32!GetLocaleFileInfo+0x3D
0x77DBF942: KERNEL32!NlsProcessInitialize+0x11D
0x77E0C6DF: KERNEL32!NlsDllInitialize+0x35
0x6A20785C: ntdll!LdrpCallInitRoutine+0x14
0x6A205393: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DD80: ntdll!LdrpInitializeProcess+0xAF6
--------------------------------------
Handle 0x7CC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3180: ntoskrnl!ObpCreateHandle+0x304
0x801E1563: ntoskrnl!ObOpenObjectByName+0x1E9
0x77DBFCD6: KERNEL32!GetLocaleFileInfo+0x3D
0x77DBF942: KERNEL32!NlsProcessInitialize+0x11D
0x77E0C6DF: KERNEL32!NlsDllInitialize+0x35
0x6A20785C: ntdll!LdrpCallInitRoutine+0x14
0x6A205393: ntdll!LdrpRunInitializeRoutines+0x1D9
0x6A20DD80: ntdll!LdrpInitializeProcess+0xAF6
--------------------------------------
Parsed 0x1CA stack traces.
Dumped 0x2 stack traces.
Dumpinformatie over alle ingangen in proces 815328b0
kd> !htrace 0 81400300
Process 0x81400300
ObjectTable 0xE10CCF60
--------------------------------------
Handle 0x7CC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7CC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE23B2: KERNEL32!CreateSemaphoreA+0x66
0x010011C5: badhandle!main+0x45
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - BAD REFERENCE:
0x8018F709: ntoskrnl!ExMapHandleToPointerEx+0xEA
0x801E10F2: ntoskrnl!ObReferenceObjectByHandle+0x12C
0x801902BE: ntoskrnl!NtSetEvent+0x6C
0x80154965: ntoskrnl!_KiSystemService+0xC4
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE265C: KERNEL32!CreateEventA+0x66
0x010011A0: badhandle!main+0x20
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Parsed 0x6 stack traces.
Dumped 0x5 stack traces.
Dumpinformatie over handle 7DC in het huidige proces
kd> !htrace 7DC
Process 0x81400300
ObjectTable 0xE10CCF60
--------------------------------------
Handle 0x7DC - BAD REFERENCE:
0x8018F709: ntoskrnl!ExMapHandleToPointerEx+0xEA
0x801E10F2: ntoskrnl!ObReferenceObjectByHandle+0x12C
0x801902BE: ntoskrnl!NtSetEvent+0x6C
0x80154965: ntoskrnl!_KiSystemService+0xC4
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE265C: KERNEL32!CreateEventA+0x66
0x010011A0: badhandle!main+0x20
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Parsed 0x6 stack traces.
Dumped 0x3 stack traces.
Heap-fouten opsporen
Heap-verificator voor foutopsporingsprogramma
De heap-foutopsporingsprogrammaextensie maakt deel uit van de !heap-extensie (NT heap debugger extension). Eenvoudige hulp kan worden verkregen met !heap -? of uitgebreider met !heap -p -? . De huidige extensie detecteert zelfstandig niet of pagina heap is ingeschakeld voor een proces en daarnaar handelen. Voorlopig moet de gebruiker van de extensie weten dat page heap is ingeschakeld en opdrachten gebruiken die voorafgegaan zijn door !heap -p. Zie !heap in de documentatie voor foutopsporing voor meer informatie over de extensie !htrace.
!heap -p
Geeft adressen weer van alle volledige paginaheaps die in het proces zijn gemaakt.
!heap -p -h ADDRESS-OF-HEAP
Volledige dump van de volledige paginaheap bij ADDRESS-OF-HEAP.
!heap -p -a ADDRESS
Controleert of er een heap-blok bij ADDRESS is. Deze waarde hoeft niet het adres van het begin van het blok te zijn. De opdracht is handig als er geen idee is over de aard van een geheugengebied.
Heap-bewerkingslogboek
Het heap-bewerkingslogboek houdt alle heap-routines bij. Deze omvatten HeapAlloc, HeapReAlloc en HeapFree.
U kunt de !avrf -hp Length extensieopdracht gebruiken om de laatste verschillende records weer te geven; Lengte geeft het aantal records op.
U kunt !avrf -hp -a Address gebruiken om alle heap-bewerkingen weer te geven die van invloed waren op het opgegeven adres. Voor een toewijzingsbewerking is het voldoende dat Adres zich in het toegewezen heap-blok bevindt. Voor een gratis bewerking moet het exacte adres van het begin van het blok worden opgegeven.
Voor elke vermelding in het logboek wordt de volgende informatie weergegeven:
- De heap-functie aangeroepen.
- De thread-id van de thread die de routine heeft genoemd.
- Het adres dat betrokken is bij de oproep- dit is het adres dat is geretourneerd door een toewijzingsroutine of die is doorgegeven aan een gratis routine.
- De grootte van de regio die betrokken is bij de oproep.
- De stacktrace van de aanroep.
De meest recente items worden eerst weergegeven.
In dit voorbeeld worden de twee meest recente vermeldingen weergegeven:
0:001> !avrf -hp 2
alloc (tid: 0xFF4):
address: 00ea2fd0
size: 00001030
00403062: Prymes!_heap_alloc_dbg+0x1A2
00402e69: Prymes!_nh_malloc_dbg+0x19
00402e1e: Prymes!_malloc_dbg+0x1E
00404ff3: Prymes!_stbuf+0xC3
00401c23: Prymes!printf+0x43
00401109: Prymes!main+0xC9
00402039: Prymes!mainCRTStartup+0xE9
77e7a278: kernel32!BaseProcessStart+0x23
alloc (tid: 0xFF4):
address: 00ea07d0
size: 00000830
00403062: Prymes!_heap_alloc_dbg+0x1A2
00402e69: Prymes!_nh_malloc_dbg+0x19
00402e1e: Prymes!_malloc_dbg+0x1E
00403225: Prymes!_calloc_dbg+0x25
00401ad5: Prymes!__initstdio+0x45
00401f38: Prymes!_initterm+0x18
00401da1: Prymes!_cinit+0x21
00402014: Prymes!mainCRTStartup+0xC4
77e7a278: kernel32!BaseProcessStart+0x23
Typische foutopsporingsscenario's
Er zijn verschillende foutscenario's die kunnen worden aangetroffen. Sommigen van hen vereisen nogal wat rechercheurwerk om het hele beeld te krijgen.
Toegangsschending op niet-toegankelijke pagina
Dit gebeurt wanneer de volledige paginaheap is ingeschakeld als de geteste toepassing toegang heeft tot voorbij het einde van de buffer. Het kan ook gebeuren als het een vrijgeraakt blok raakt. Als u wilt weten wat de aard is van het adres waarop de uitzondering is opgetreden, moet u het volgende gebruiken:
!heap –p –a ADDRESS-OF-AV
Beschadigd blokbericht
Op verschillende momenten tijdens de levensduur van een toewijzing (toewijzing, gebruikersvrij, echt gratis) controleert de heap-manager van de pagina of het blok alle opvulpatronen intact heeft en de blokkop consistente gegevens bevat. Als dit niet het geval is, krijgt u een verificatiestop.
Als het blok een volledige pagina heap blok is (bijvoorbeeld als u zeker weet dat de volledige pagina heap is ingeschakeld voor alle toewijzingen), kunt u '!heap -p -a ADDRESS' gebruiken om de kenmerken van het blok te achterhalen.
Als het blok een licht paginaheapblok is, moet u het beginadres voor de blokheader achterhalen. U vindt het beginadres door 30-40 bytes onder het gerapporteerde adres te dumpen en te zoeken naar de magische begin-/eindpatronen voor een blokkop (ABCDAAAA, ABCDBBBB, ABCDAAA9, ABCDBBBA).
De header geeft alle informatie die u nodig hebt om de fout te begrijpen. In het bijzonder zullen de magische patronen aangeven of het blok is toegewezen of vrij, afhankelijk van of het een "light page heap" of een "full page heap" blok is. De informatie hier moet zorgvuldig worden afgestemd op het beledigde gesprek.
Als er bijvoorbeeld een aanroep naar HeapFree wordt gedaan met het adres van een blok plus vier bytes, krijgt u het beschadigde bericht. De blokkop ziet er goed uit, maar u zult moeten merken dat de eerste byte na het einde van de header (eerste byte na 0xDCBAXXXX magic value) een ander adres heeft dan de byte in de aanroep.
Speciale opvulpunten
De pagina-heapmanager vult de geheugentoewijzing van de gebruiker met waarden die lijken op kernel-pointers. Dit gebeurt wanneer het blok wordt vrijgemaakt (opvulwaarde is F0) en wanneer het blok wordt toegewezen, maar er geen aanvraag wordt gedaan om het blok te nulen (opvulwaarde is E0 voor lichte pagina heap en C0 voor volledige pagina heap). De niet-nultoewijzingen zijn typisch voor gebruikers van malloc/new. Als er een fout is opgetreden (toegangsfout) waarbij een lees-/schrijfbewerking wordt uitgevoerd op adressen zoals F0F0F0F0, E0E0E0E0, C0C0C0C0, raakt u waarschijnlijk een van deze gevallen.
Een lees- of schrijfbewerking op F0F0F0F0 betekent dat er een blok is gebruikt nadat het is vrijgemaakt. Helaas hebt u wat rechercheurwerk nodig om erachter te komen welk blok dit heeft veroorzaakt. Je moet de stack-trace van de fout ophalen en vervolgens de code voor de functies op de stack inspecteren. Een van hen kan een verkeerde aanname maken over een toewijzing die actief is.
Een lees-/schrijfbewerking op E0E0E0E0/C0C0C0C0 betekent dat de toepassing de toewijzing niet juist heeft geïnitialiseerd. Hiervoor is ook codecontrole van de functies in de huidige stacktracering vereist. Hier volgt een voorbeeld voor dit soort fouten. Tijdens een testproces werd een toegangsfout opgemerkt tijdens het uitvoeren van een HeapFree op het adres E0E0E0E0. Het bleek dat de test een structuur had toegewezen, deze niet correct had geïnitialiseerd en vervolgens de destructor van het object had aangeroepen. Omdat een bepaald veld niet null was (het bevatte E0E0E0E0), werd de delete-functie erop aangeroepen.
Technische details van pagina-heap
Om heap-beschadigingen (overlopen of onderlopen) te detecteren, wijzigt AppVerifier de manier waarop geheugen wordt toegewezen door het aangevraagde geheugen op te vullen met volledige niet-beschrijfbare pagina's of met speciale tags voor en na het toegewezen geheugen. AppVerifier doet dit door Verifier.dll te laden in het proces dat geverifieerd wordt en sommige van de Win32 Heap API's die door de toepassing worden aangeroepen, om te leiden naar bijbehorende Verifier.dll API's.
Wanneer u het aangevraagde geheugen opvult met volledige niet-schrijfbare pagina's (de instelling VOLLEDIG is ingeschakeld in de sectie heap-eigenschappen van de pagina en de standaardinstelling is), verbruikt AppVerifier een grote hoeveelheid virtueel geheugen, maar heeft het voordeel dat heap-beschadigingsgebeurtenissen in de cache worden opgeslagen in realtime wanneer de overloop of onderloop optreedt. Houd er rekening mee dat het geheugen in deze modus er als volgt uitziet [AppVerifier Read-Only Heap-pagina (4k)] [Hoeveelheid geheugen aangevraagd door de toepassing onder test] of zoals deze [Hoeveelheid geheugen die is aangevraagd door toepassing onder test] [AppVerifier Read-Only Heap-pagina (4k)].
De heapcontrole plaatst een guard-pagina aan het begin of het einde van de toewijzing, afhankelijk van de Backward-eigenschap. Als Terugwaarts is ingesteld op Onwaar, wat standaard is, wordt er een beveiligingspagina aan het einde van de toewijzing geplaatst om bufferoverschrijdingen op te sporen. Als deze is ingesteld op True, wordt de guard page aan het begin van de toewijzing geplaatst om buffer underruns te detecteren.
Wanneer u het aangevraagde geheugen opvult met speciale tags (ingeschakeld door het selectievakje Volledig uit te schakelen in de heap-eigenschappen), controleert AppVerifier u en waarschuwt u wanneer dit geheugen wordt vrijgegeven. Het belangrijkste probleem bij het gebruik van deze techniek is dat er enkele gevallen zijn wanneer de geheugenbeschadiging alleen wordt gedetecteerd wanneer het geheugen wordt vrijgegeven (de minimale hoeveelheid geheugenblok is 8 bytes), dus wanneer op een variabele van 3 bytes of een overloop van 5 bytes wordt gedetecteerd, wordt deze niet onmiddellijk gedetecteerd.
Bij een underflow event zal worden geprobeerd om naar een Read-Only-pagina te schrijven. Hiermee wordt een uitzondering geactiveerd. Houd er rekening mee dat deze uitzondering alleen kan worden opgevangen als de doeltoepassing wordt uitgevoerd onder een foutopsporingsprogramma. Houd er rekening mee dat de heap-modus voor volledige pagina deze fouten ook kan detecteren omdat er padding en guard-pagina's worden gebruikt. De reden waarom u 'light page heap' zou gebruiken, is als uw computer de hoge geheugeneisen van 'full page heap' niet verdraagt.
Voor geheugenintensieve toepassingen of wanneer het nodig is om AppVerifier gedurende lange tijd te gebruiken (bijvoorbeeld stresstests), is het beter om normale (lichte) heap-tests uit te voeren in plaats van in de volledige modus vanwege de prestatievermindering. Wanneer u echter een probleem tegenkomt, schakelt u de volledige paginaheap in om verder te onderzoeken.
Toepassingen die gebruikmaken van aangepaste heaps (een heap die de implementatie van de heap van het besturingssysteem omzeilt) kunnen mogelijk niet volledig profiteren van het gebruik van paginaheap, of zelfs niet goed functioneren wanneer deze functie is ingeschakeld.
Foutopsporing van geheugenfouten
De extensie voor foutopsporingsprogramma voor geheugenverificator
In het bewerkingslogboek voor virtuele ruimte worden alle routines bijgehouden waarmee de virtuele ruimte van een proces op welke manier dan ook wordt gewijzigd. Deze omvatten VirtualAlloc, VirtualFree, MapViewOfFile en UnmapViewOfFile.
U kunt de !avrf -vs Length extensieopdracht gebruiken om de laatste verschillende records weer te geven; Lengte geeft het aantal records op.
U kunt !avrf -vs -a Address gebruiken om alle virtuele ruimtebewerkingen weer te geven die van invloed zijn op het opgegeven adres. Voor een toewijzing is het voldoende dat adres zich in het toegewezen blok bevindt. Voor een gratis aanvraag moet het exacte adres van het begin van de regio worden opgegeven.
Voor elke vermelding in het logboek wordt de volgende informatie weergegeven:
- De functie wordt aangeroepen
- De thread-id van de thread die de routine aangeroepen heeft
- Het adres dat betrokken is bij de oproep - dit is het adres dat is geretourneerd door een toewijzingsroutine of die is doorgegeven aan een gratis routine
- De grootte van de regio die betrokken is bij de oproep
- Het type geheugenbewerking (de parameter AllocationType)
- Het type beveiliging aangevraagd
- De stack trace voor de aanroep
Voorbeelden
De meest recente items worden eerst weergegeven.
In het volgende voorbeeld worden de twee meest recente vermeldingen weergegeven:
0:001> !avrf -vs 2
VirtualFree (tid: 0xB4): addr:04bb0000 sz:00400000 op:8000 prot:0
00aa1ac2: verifier!VsLogCall+0x42
00aa19c1: verifier!AVrfpNtFreeVirtualMemory+0x30
68925d17: kernel32!VirtualFreeEx+0x35
6892611c: kernel32!VirtualFree+0x13
75ef6525: mshtml+0x116525
75ef68af: mshtml+0x1168AF
6a20787c: ntdll!LdrpCallInitRoutine+0x14
6a211c6f: ntdll!LdrUnloadDll+0x39A
689275c1: kernel32!FreeLibrary+0x3B
77b22d69: ole32!CoQueryReleaseObject+0x1E6
77b02bd2: ole32!SetErrorInfo+0x1ED
VirtualFree (tid: 0xB4): addr:04bb0000 sz:00001000 op:4000 prot:0
00aa1ac2: verifier!VsLogCall+0x42
00aa19c1: verifier!AVrfpNtFreeVirtualMemory+0x30
68925d17: kernel32!VirtualFreeEx+0x35
6892611c: kernel32!VirtualFree+0x13
75ef65ae: mshtml+0x1165AE
75ef68af: mshtml+0x1168AF
6a20787c: ntdll!LdrpCallInitRoutine+0x14
6a211c6f: ntdll!LdrUnloadDll+0x39A
689275c1: kernel32!FreeLibrary+0x3B
77b22d69: ole32!CoQueryReleaseObject+0x1E6
77b02bd2: ole32!SetErrorInfo+0x1ED
Uit de uitvoer blijkt dat thread 0xB4 eerst een pagina heeft ontbonden en vervolgens de hele virtuele regio heeft vrijgegeven.
Hier volgt een weergave van alle bewerkingen die van invloed zijn op het adres 0x4BB1000:
0:001> !avrf -vs -a 4bb1000
Searching in vspace log for address 04bb1000 ...
VirtualFree (tid: 0xB4): addr:04bb0000 sz:00400000 op:8000 prot:0
00aa1ac2: verifier!VsLogCall+0x42
00aa19c1: verifier!AVrfpNtFreeVirtualMemory+0x30
68925d17: kernel32!VirtualFreeEx+0x35
6892611c: kernel32!VirtualFree+0x13
75ef6525: mshtml+0x116525
75ef68af: mshtml+0x1168AF
6a20787c: ntdll!LdrpCallInitRoutine+0x14
6a211c6f: ntdll!LdrUnloadDll+0x39A
689275c1: kernel32!FreeLibrary+0x3B
77b22d69: ole32!CoQueryReleaseObject+0x1E6
77b02bd2: ole32!SetErrorInfo+0x1ED
VirtualFree (tid: 0xB4): addr:04bb1000 sz:00001000 op:4000 prot:0
00aa1ac2: verifier!VsLogCall+0x42
00aa19c1: verifier!AVrfpNtFreeVirtualMemory+0x30
68925d17: kernel32!VirtualFreeEx+0x35
6892611c: kernel32!VirtualFree+0x13
75ef65ae: mshtml+0x1165AE
75ef68af: mshtml+0x1168AF
6a20787c: ntdll!LdrpCallInitRoutine+0x14
6a211c6f: ntdll!LdrUnloadDll+0x39A
689275c1: kernel32!FreeLibrary+0x3B
77b22d69: ole32!CoQueryReleaseObject+0x1E6
77b02bd2: ole32!SetErrorInfo+0x1ED
VirtualAlloc (tid: 0xB4): addr:04bb0000 sz:00010000 op:1000 prot:4
00aa1ac2: verifier!VsLogCall+0x42
00aa1988: verifier!AVrfpNtAllocateVirtualMemory+0x37
68925ca3: kernel32!VirtualAllocEx+0x61
68926105: kernel32!VirtualAlloc+0x16
75ef63f3: mshtml+0x1163F3
VirtualAlloc (tid: 0xB4): addr:04bb0000 sz:00400000 op:2000 prot:4
00aa1ac2: verifier!VsLogCall+0x42
00aa1988: verifier!AVrfpNtAllocateVirtualMemory+0x37
68925ca3: kernel32!VirtualAllocEx+0x61
68926105: kernel32!VirtualAlloc+0x16
75ef63d9: mshtml+0x1163D9
Als u deze uitvoer wilt lezen, moet u er rekening mee houden dat de vermeldingen worden gedumpt vanaf de meest recente. In dit logboek ziet u dus dat thread 0xB4 een grote regio heeft toegewezen waarin een pagina is gecommit. Later werd de pagina gedecommitteerd en vervolgens de hele virtuele regio vrijgegeven.
Zie ook
Application Verifier - Overzicht
Toepassingsverificator : toepassingen testen
Application Verifier - Tests binnen toepassingsverificator