Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
Hibakereső telepítése és beállítása
Egyes Application Verifier-műveletek kivételt eredményezhetnek. A hibakeresőt úgy kell beállítani, hogy ezeket a kivételeket a második lehetőségen észlelje, mivel maga az Application Verifier fogja kezelni az első esélybeli kivételeket.
A bevezetett kivételek három típusból állnak:
A rendszer hozzáférési szabálysértési kivételt (0xC0000005) hoz létre, ha a halombeállítás a halompuffer túlfutását észleli. Bizonyos esetekben a Rendszerútvonal használatának ellenőrzése beállítás hozzáférés-megsértést is okozhat.
Érvénytelen leírókivétel (0xC0000008) jön létre, ha az Érvénytelen leíróhasználat észlelése beállítás érvénytelen leíróműveletet észlel.
A rendszer egy verem túlcsordulási kivételt (0xC00000FD) hoz létre, amikor a Megfelelő verem ellenőrzése beállítás azt észleli, hogy a kezdeti verem túl rövid volt.
Az események előkészítésének egyik módja, ha elindítja a hibakeresőt egy parancssorban az alábbiak szerint:
windbg -xd av -xd ch -xd sov ApplicationCommandLine
vagy
cdb -xd av -xd ch -xd sov ApplicationCommandLine
Ha már elindította a hibakeresőt, az sxd (Kivételek beállítása) paranccsal észlelheti az összes hozzáférés-szabálysértést, érvénytelen leírót és verem-túlcsordulást második esélyű kivételként:
0:000> sxd av
0:000> sxd ch
0:000> sxd sov 1
Elméletileg egy kernel-hibakeresőn keresztül vezérelhető az Application Verifier. Ez azonban nem ajánlott – a .process és a .pagein parancsok gyakori használatát igényli, de nem ad több energiát, mint egy felhasználói módú hibakereső használata.
A hibakeresési eszközök telepítése
Az eszközök legújabb verziójának letöltéséhez tekintse meg a Windows hibakeresési eszközeinek letöltésével kapcsolatos témakört.
Hardver konfigurálása User-Mode hibakereséshez
A felhasználói módú hibakeresés általában egyetlen gépen történik: a hibakereső ugyanazon a számítógépen fut, mint a sikertelen alkalmazás.
Ebben az esetben nincs szükség konkrét hardverbeállításra. Ebben a témakörben a gazdaszámítógép és a célszámítógép kifejezés ebben az esetben felcserélhető.
Szoftver konfigurálása User-Mode hibakereséshez
Alapszintű User-Mode konfiguráció – A felhasználói módú hibakeresés megkezdése előtt le kell töltenie a szükséges szimbólumfájlokat, és be kell állítania bizonyos környezeti változókat.
Szimbólumfájlok
Le kell töltenie a hibakeresés alatt álló felhasználói módú folyamat szimbólumfájljait. Ha ez egy ön által írt alkalmazás, akkor teljes szimbólumfájlokkal kell rendelkeznie. Ha kereskedelmi alkalmazásról van szó, a szimbólumfájlok elérhetőek lehetnek egy webkiszolgálón, vagy letölthetők, forduljon a gyártóhoz.
ha távoli hibakeresést végez, a szimbólumfájl helye a használt módszertől függ:
Ha távoli hibakeresést végez a hibakeresőn keresztül, a szimbólumfájloknak a hibakereső kiszolgálóval rendelkező számítógépen kell lenniük.
Ha távoli hibakeresést végez remote.exekeresztül, a szimbólumfájloknak a hibakeresővel együtt kell lenniük a számítógépen.
Ha távoli hibakeresést végez egy folyamatkiszolgálón vagy egy KD kapcsolatkiszolgálón keresztül, a szimbólumfájloknak az intelligens ügyféllel együtt kell lenniük a számítógépen.
Ha a felhasználói módú hibakeresőt a kernel-hibakeresőből vezérli, a szimbólumfájloknak mindkét számítógépen meg kell lenniük.
Környezeti változók konfigurálása
A hibakereső számos környezeti változót használ számos fontos beállítás jelzésére.
További információ a hibakeresőkről: Első lépések a Windows hibakeresésével kapcsolatban
Az Application Verifier konfigurálása a hibakeresővel a parancssor használatával
Az Application Verifier konfigurálásához használhatja a CDB vagy az NTSD parancssort.
Használja a következő parancssort:
cdb OtherOptions -vf:Flags Target
Ahol a Cél a célalkalmazás neve, a Jelzők pedig a célalkalmazásra alkalmazni kívánt Alkalmazás-ellenőrző beállításokat adja meg.
A jelölőknek a kívánt beállításokat képviselő bitek összegének kell lenniük. Az egyes bitértékek a következők:
| Zászló érték | Értelmezés |
|---|---|
| 00000001 | HEAP-ELLENŐRZÉSEK |
| 00000004 | ELLENŐRZÉSEK KEZELÉSE |
| 00000008 | ALACSONY ERŐFORRÁSÚ SIM-KÁRTYA ELLENŐRZÉSEK |
| 00000020 | TLS-ELLENŐRZÉSEK |
| 00000040 | SZENNYEZETT VEREMEK |
| 00000200 | VESZÉLYES API-K |
| 00001000 | Kivétel ellenőrzések |
| 00002000 | MEMÓRIAELLENŐRZÉSEK |
| 00020000 | EGYÉB ELLENŐRZÉSEK |
| 00040000 | ZÁROLÁSI ELLENŐRZÉSEK |
Hibakeresés a!avrf használatával
A !avrf bővítmény szabályozza az Application Verifier beállításait, és az Application Verifier által előállított különféle kimeneteket jeleníti meg. A !arvrf bővítményről további információt a hibakereső dokumentációjában található !avrf című témakörben talál.
Szemantika
!avrf
A paraméterek nélküli !avrf parancs megjeleníti az Application Verifier beállításait, valamint az aktuális és az előző Application Verifier-törésekkel kapcsolatos információkat, ha vannak ilyenek.
!avrf –vs { Length | -aAddress }
Megjeleníti a virtuális tér műveleti naplót. A Hossz a legutóbbitól kezdődően megjelenítendő rekordok számát adja meg. A cím a virtuális címet adja meg. Ekkor megjelennek az ezt a virtuális címet tartalmazó virtuális műveletek rekordjai.
!avrf -hp { Length | -a Address }
Megjeleníti a halomműveleti naplót. A cím a halomcímet adja meg. Megjelennek az ezt a halomcímet tartalmazó halomműveletek rekordjai.
!avrf -cs { Length | -a Address }
Megjeleníti a kritikus szakasz törlési naplót. A Hossz a legutóbbitól kezdődően megjelenítendő rekordok számát adja meg. A cím a kritikus szakasz címét adja meg. A cím megadásakor megjelennek az adott kritikus szakasz rekordjai.
!avrf -dlls [ Length ]
Megjeleníti a DLL betöltési/eltávolítási naplót. A Hossz a legutóbbitól kezdődően megjelenítendő rekordok számát adja meg.
!avrf -trm
Megjeleníti az összes megszakított és felfüggesztett szál naplóját.
!avrf -ex [ Length ]
Megjeleníti a kivételnaplót. Az Application Verifier nyomon követi az alkalmazásban történt összes kivételt.
!avrf -threads [ ThreadID ]
A célfolyamat szálairól jelenít meg információkat. A gyermekszálak esetében a verem mérete és a szülő által megadott CreateThread jelzők is megjelennek. A szálazonosító megadása csak az adott szálra vonatkozó információkat jeleníti meg.
!avrf -tp [ ThreadID ]
Megjeleníti a szálkészlet naplót. Ez a napló különböző műveletekhez tartalmazhat veremnyomokat, például a szál affinitási maszkjának módosítását, a szál prioritásának módosítását, a szálüzenetek közzétételét, a COM inicializálását és a COM leállítását a szálkészleti visszahívás során. A szálazonosító megadása csak az adott szálra vonatkozó információkat jeleníti meg.
!avrf -srw [ Address | Address Length ] [ -stats ]
Megjeleníti a Slim Reader/Writer (SRW) naplót. A Cím megadása az adott SRW-zárolási címmel kapcsolatos rekordokat jeleníti meg. Ha a címmel együtt meg van adva a hossz, a címtartományon belüli összes SRW-zárolás megjelenik. A -stats beállítás kiírja az SRW zárolási statisztikáit.
!avrf -leak [ -m ModuleName ] [ -r ResourceType ] [ -a Address ] [ -t ]
Megjeleníti a kiemelkedő erőforrás-naplót. Előfordulhat, hogy ezek az erőforrások egy adott ponton szivárognak vagy sem. A ModuleName megadása (a bővítményt is beleértve) a megadott modulban lévő összes rendelkezésre álló erőforrást megjeleníti. A ResourceType megadása megjeleníti az adott erőforrástípushoz tartozó kinnlévő erőforrásokat. A Cím megadása az adott címmel rendelkező, függőben lévő erőforrások rekordjait adja meg. A ResourceType az alábbiak egyike lehet:
- Halom: A halomfoglalások megjelenítése Win32 Halom API-k használatával
- Helyi: Helyi/globális foglalások megjelenítése
- CRT: A foglalások megjelenítése CRT API-k igénybevételével
- Virtuális: Virtuális foglalások megjelenítése
- BSTR: A BSTR-foglalások megjelenítése
- Beállításjegyzék: Megnyílik a beállításkulcs megjelenítése
- Power: Energiaértesítési objektumok megjelenítése
- Leíró: Szál-, fájl- és eseményleíró-foglalások megjelenítése
!avrf –trace TraceIndex
Megjeleníti a megadott nyomkövetési index veremkövetését. Egyes struktúrák ezt a 16 bites indexszámot használják a veremkövetés azonosításához. Ez az index a veremnyom adatbázisban található egyik helyre mutat. Ha ilyen struktúrát elemez, hasznosnak fogja találni ezt a szintaxist.
!avrf -cnt
A globális számlálók listáját jeleníti meg.
!avrf -brk [ BreakEventType ]
Megadja, hogy ez egy eseménytörési parancs. Ha !avrf -brk további paraméterek nélkül használják, a törésesemény-beállítások megjelennek. A BreakEventType a törésesemény típusszámát adja meg. A lehetséges típusok listájához használja !avrf -brka következőt: .
!avrf -flt [ EventTypeProbability ]
Meghatározza, hogy ez egy hibainjektálási parancs. Ha !avrf -flt további paraméterek nélkül használják, az aktuális hibainjektálási beállítások jelennek meg. Az EventType az esemény típusszámát adja meg. A valószínűség azt a gyakoriságot határozza meg, amellyel az esemény meghiúsul. Ez lehet 0 és 1 000 000 000 közötti egész szám (0xF4240).
!avrf -flt break EventType
Az Application Verifier a hiba minden egyes beadásakor feltöri a hibakeresőt.
!avrf -flt stacks Length
Megjeleníti a legutóbbi hibainjektált műveletek veremnyomainak hosszát.
!avrf -trg [ StartEnd | dll Module | all ]
Meghatározza, hogy ez egy céltartomány-parancs. Ha a -trg-t további paraméterek nélkül használják, az aktuális céltartományok jelennek meg. A Start a céltartomány vagy a kizárási tartomány kezdőcímét adja meg. A Végpont a céltartomány vagy a kizárási tartomány zárócímét adja meg. A modul a megcélzandó vagy kizárandó modul nevét adja meg. A modulnak tartalmaznia kell a modul teljes nevét, beleértve a .exe vagy .dll bővítményt. Az elérésiút-információkat nem szabad megadni. Ha az összeset megadja, az összes céltartomány vagy kizárási tartomány alaphelyzetbe állítódik.
!avrf -skp [ StartEnd | dll Module | all | Time ]
Azt adja meg, hogy ez egy kizárási tartomány parancsa. A Start a céltartomány vagy a kizárási tartomány kezdőcímét adja meg. A Végpont a céltartomány vagy a kizárási tartomány zárócímét adja meg. A modul a megcélzandó vagy kizárandó modul nevét adja meg. A modulnak tartalmaznia kell a modul teljes nevét, beleértve a .exe vagy .dll bővítményt. Az elérésiút-információkat nem szabad megadni. Ha az összes meg van adva, az összes céltartomány vagy kizárási tartomány alaphelyzetbe áll. Az idő megadása miatt a végrehajtás folytatása után az idő ezredmásodpercben minden hiba el lesz tiltva.
A hibakeresőben a !avrf parancs által megadott kimenet a következő.
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 bővítmény megjegyzései
Ha a !avrf bővítményt paraméterek nélkül használja, az aktuális Application Verifier-beállításokat jeleníti meg.
A !avrf bővítmény a hibakereső Exts.dll használja.
Ha egy Application Verifier stop történt, a paraméterek nélküli !avrf bővítmény megmutatja a leállítás jellegét és az azt okozó tényezőket.
Ha hiányoznak ntdll.dll és verifier.dll szimbólumai, az !avrf bővítmény hibaüzenetet fog generálni.
Folytonos és Nem-Folytonos Leállások
Folyamatos leállítás hibakeresése
Íme egy példa egy érvénytelen handle kivételre, amelyet az Érvénytelen handle használatának észlelése beállítás váltott ki.
Először a következő üzenet jelenik meg:
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
Figyelje meg, hogy az üzenet azt jelzi, hogy ez az alkalmazás-ellenőrző leállítása folytatható. Miután megismerte a történteket, folytathatja a célalkalmazás futtatását.
Először a !avrf bővítményt kell használnia. Ez az aktuális hibáról ad információt:
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).
A kijelző utolsó sora összefoglalja a problémát.
Érdemes lehet áttekinteni néhány naplót ezen a ponton. Ha végzett, a g (Go) paranccsal indítsa újra az alkalmazást:
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
Ebben az esetben az üzenet azt jelzi, hogy ez az alkalmazás-ellenőrző leállítása nem folytatható. A hiba túl súlyos ahhoz, hogy a folyamat tovább fusson, és az Application Verifier nem képes a folyamat mentésére.
A !avrf bővítmény az aktuális hibával kapcsolatos információk megadására használható:
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.
A kijelző utolsó sora összefoglalja a problémát.
Érdemes lehet néhány naplót is megnézni ezen a ponton. Ezen a ponton érdemes lehet az .restart (Restart Target Application) parancsot használni. Vagy lehet, hogy inkább befejezi az Application Verifier-munkamenetet, és elkezdi kijavítani a kód hibáit.
Kritikus szakaszhibák hibakeresése
!cs hibakereső bővítmény
A !cs a felhasználói módban hibakeresőben és a kernel-hibakeresőben is használható az aktuális folyamat kritikus szakaszaival kapcsolatos információk megjelenítéséhez. A !cs kiterjesztéssel kapcsolatos további információkért tekintse meg a !cs fájlt a hibakereső dokumentációjában.
A típusadatokkal való egyező szimbólumok megadása kötelező, különösen ntdll.dllesetében.
A bővítmény szintaxisa a következő:
!cs [-s] – írja ki az aktuális folyamat összes aktív kritikus szakaszát.
!cs [-s] cím – megjeleníti a kritikus szakaszt ezen a címen.
!cs [-s] -d cím – a DebugInfo-nak megfelelő kritikus szakasz kiíratása ezen a címen.
A -s a kritikus szakasz inicializálási verem nyomkövetését fogja kihozni, ha elérhető.
Példák:
A kritikus szakasz adatainak kiírása a cím alapján
0:001> ! cs 0x7803B0F8
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
DebugInfo = 0x6A262080
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
Kritikus szakasz információinak memóriaképe a cím felhasználásával, beleértve az inicializálási verem-nyomkövetést is.
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
A kritikus szakasz adatainak kiírása a hibakeresési információ címének használatával
0:001> !cs -d 0x6A262080
DebugInfo = 0x6A262080
Critical section = 0x7803B0F8 (MSVCRT!__app_type+0x4)
NOT LOCKED
LockSemaphore = 0x0
SpinCount = 0x0
A kritikus szakasz adatainak kiíratása a hibakeresési információ címének használatával, beleértve az inicializálási veremnyomot is.
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
Az aktuális folyamat összes aktív kritikus szakaszára vonatkozó információ kiírása
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
.....
Az aktuális folyamat összes aktív kritikus szakaszának információinak kiírása, a verem inicializálási nyomkövetésével együtt.
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
Kivételhibák hibakeresése
A kivételnapló rögzíti a célfolyamatban történt összes kivételt.
A !avrf -ex Length bővítmény parancsával megjelenítheti az utolsó néhány kivételt; A hossz a kivételek számát adja meg. Ha a hossz nincs megadva, minden kivétel megjelenik.
Íme egy példa:
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.
Hibakeresés során hibák kezelése
A !htrace a felhasználói módú hibakeresőben és a kernel-hibakeresőben is használható a folyamat egy vagy az összes leírójának veremkövetési információinak megjelenítéséhez. Ez az információ akkor érhető el, ha a folyamathoz engedélyezve van a handle követés – automatikusan engedélyezve van, ha a handle ellenőrzés engedélyezve van az alkalmazás verifikátorban. A verem nyomkövetései mentésre kerülnek minden alkalommal, amikor a folyamat megnyit vagy bezár egy leírót, vagy érvénytelen leíróra hivatkozik. A !htrace kiterjesztéssel kapcsolatos további információkért lásd: !htrace a hibakereső dokumentumokban.
A bővítmény kernel-hibakereső szintaxisa a következő:
!htrace [ handle [process] ]
Ha a fogantyú nincs megadva, vagy 0, akkor a folyamat összes fogópontjára vonatkozó információ megjelenik. Ha a folyamat nincs megadva, a rendszer az aktuális folyamatot használja.
A felhasználói módú hibakereső szintaxisa a következő:
!htrace [handle]
A felhasználói módú hibakereső bővítmény mindig megjeleníti az aktuális hibakeresési folyamat adatait.
Példák:
A 815328b0 folyamat 7CC-ének kezelésére vonatkozó memóriaképadatok
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.
A 815328b0 folyamat összes fogantyújának információinak kiírása
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.
Az aktuális folyamat 7DC számú hivatkozásának információinak kilistázása
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.
Halomhibák hibakeresése
Heap verifier debugger bővítmény
A halom ellenőrző hibakereső kiterjesztés a !halom kiterjesztés része (NT halom hibakereső kiterjesztés). Egyszerű segítséget a "!heap -?" paranccsal kaphat. vagy részletesebb a !heap -p -? . Az aktuális bővítmény önmagában nem észleli, ha a lap halom engedélyezve van egy folyamathoz, és ennek megfelelően jár el. A bővítmény felhasználójának egyelőre tudnia kell, hogy a lap heap engedélyezve van, és a !heap -p által előtagolt parancsokat kell használnia. A !htrace kiterjesztéssel kapcsolatos további információkért lásd: !heap a hibakereső dokumentációjában.
!heap -p
Kiírja az összes teljes oldallap halom címét, amelyeket a folyamat során hoztak létre.
!heap -p -h ADDRESS-OF-HEAP
Teljes memóriakép a teljes oldal halomról a ADDRESS-OF-HEAP címen.
!heap -p -a ADDRESS
Megpróbálja kideríteni, hogy van-e halomblokk a ADDRESS-ben. Ennek az értéknek nem kell a blokk elejének címe lenni. A parancs akkor hasznos, ha nincs semmilyen nyom a memóriaterület természetéről.
Halomműveleti napló
A halomművelet naplója nyomon követi az összes halom rutint. Ezek közé tartozik a HeapAlloc, a HeapReAlloc és a HeapFree.
A !avrf -hp Length bővítményparancs használatával megjelenítheti az utolsó több rekordot; A hossz a rekordok számát határozza meg.
Az !avrf -hp -a Address használatával megjelenítheti az összes halomhely műveletet, amely hatással volt a megadott címre. Foglalási művelet esetén elegendő, ha a cím szerepel a lefoglalt halomblokkban. Ingyenes művelet esetén meg kell adni a blokk elejének pontos címét.
A napló minden egyes bejegyzése esetében a következő információk jelennek meg:
- A heap függvényt hívták meg.
- Annak a szálnak a szálazonosítója, amely a rutint meghívta.
- A hívásban érintett cím – ez az a cím, amelyet egy foglalási rutin adott vissza, vagy amelyet egy ingyenes rutinnak adott át.
- A hívásban érintett régió mérete.
- A hívás veremnyoma.
A legutóbbi bejegyzések jelennek meg először.
Ebben a példában a két legutóbbi bejegyzés jelenik meg:
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
Tipikus hibakeresési forgatókönyvek
Több hibaforgatókönyv is előfordulhat. Néhányat közülük elég sok nyomozói munkára van szükség ahhoz, hogy teljes képet kapjunk.
Hozzáférés megsértése nem akadálymentes lapon
Ha a teljes oldalas halom engedélyezve van, ez akkor fordul elő, ha a tesztelt alkalmazás a pufferhatáron túl fér hozzá. Ez akkor is előfordulhat, ha egy felszabadított blokkot érint. A kivételt okozó cím természetének megértéséhez a következőt kell használnia:
!heap –p –a ADDRESS-OF-AV
Sérült blokküzenet
A foglalás élettartama alatt (foglalás, felhasználó szintű felszabadítás, valós szintű felszabadítás) a lap kupackezelő ellenőrzi, hogy a blokk minden kitöltési mintája érintetlen-e, és hogy a blokkfejléc konzisztens adatokat tartalmaz-e. Ha ez nem így van, akkor egy ellenőrzési leállás történik.
Ha a blokk egy teljes oldalas halomblokk (például ha biztos benne, hogy a teljes oldal halom minden foglaláshoz engedélyezve van), akkor a "!heap –p –a ADDRESS" használatával megtudhatja, hogy mik a blokk jellemzői.
Ha a blokk egy egyszerű oldal halomblokk, akkor meg kell tudnia a blokk fejlécének kezdő címét. A kezdőcímet úgy találhatja meg, hogy a jelentett cím alatti 30–40 bájtot kiment, és megkeresi a blokkfejlécek jellegzetes kezdő/záró mintáit (ABCDAAAA, ABCDBBBB, ABCDAAA9, ABCDBBBA).
A fejléc minden olyan információt megad, amely a hiba megértéséhez szükséges. Különösen a mágikus mintázatok jelzik, hogy a blokk ki van-e osztva vagy szabad, illetve hogy egy kis lapkészlet vagy egy teljes lapkészlet blokkja. Az itt található információkat gondosan össze kell egyeztetni a jogsértő hívással.
Ha például a HeapFree hívása egy blokk címével és négy bájttal történik, akkor a sérült üzenet jelenik meg. A blokkfejléc jól fog kinézni, de látnia kell, hogy a fejléc vége utáni első bájt (a 0xDCBAXXXX mágikus érték után az első bájt) egy másik címmel rendelkezik, mint a hívásban.
Speciális kitöltési mutatók
Az oldalhalom-kezelő a felhasználói foglalást olyan értékekkel tölti ki, amelyek kernelmutatóknak tűnnek. Ez akkor fordul elő, amikor a blokk felszabadul (a kitöltési érték F0), és amikor a blokk le lesz foglalva, de nincs kérés a blokk nullázására (a könnyű oldalhalomnál a kitöltési érték E0, a teljes oldalhalomnál pedig C0). A nem nullázott foglalások tipikusan a malloc/new használókra jellemzőek. Ha hiba (hozzáférés-megsértés) történik, amikor olvasási/írási kísérleteket kísérel meg olyan címeken, mint a F0F0F0F0, E0E0E0E0, C0C0C0C0, akkor valószínűleg az egyik ilyen esetet éri el.
Az F0F0F0F0 címen történő olvasás/írás azt jelenti, hogy egy blokkot használtak, miután felszabadult. Sajnos szüksége lesz néhány nyomozói munkára, hogy megtudja, melyik blokk okozta ezt. Le kell kérnie a hiba verem-nyomkövetését, majd meg kell vizsgálnia a veremen lévő függvények kódját. Az egyikük tévesen feltételezheti, hogy egy allokáció még él.
A E0E0E0E0/C0C0C0C0 olvasási/írási művelet azt jelenti, hogy az alkalmazás nem inicializálta megfelelően a foglalást. Ehhez az aktuális veremkövetésben lévő függvények kódvizsgálatára is szükség van. Íme egy példa erre a hibára. A tesztelési folyamat során egy hozzáférési jogsértést észleltek a HeapFree művelet végrehajtása közben, a cím E0E0E0E0 esetén. Kiderült, hogy a teszt lefoglalt egy struktúrát, nem helyesen inicializálta, majd meghívta az objektum destruktorát. Mivel egy adott mező nem null értékű (E0E0E0E0 volt benne), törlést hívott meg rajta.
Laphalom Technikai Részletei
A halomsérülések (túlcsordulások vagy alulcsordulások) észleléséhez az AppVerifier úgy módosítja a memória lefoglalásának módját, hogy a kért memóriát teljes, nem írható lapokkal vagy speciális címkékkel osztja ki a lefoglalt memória előtt és után. Az AppVerifier úgy működik, hogy betölti a Verifier.dll-t az ellenőrzött folyamatba, és átirányítja az alkalmazás által hívott Win32 Halom API-kat a megfelelő Verifier.dll API-khoz.
Ha a kért memóriát teljes, nem írható lapokkal kitölti (a TELJES beállítás engedélyezve van a lap halomtulajdonságok szakaszában, és ez az alapértelmezett beállítás), az AppVerifier nagy mennyiségű virtuális memóriát fog használni, de előnye, hogy a halomsérülési események valós időben gyorsítótárazódnak a túlcsordulás vagy az alulcsordulás bekövetkezésekor. Ne feledje, hogy a memória ebben a módban a következőképpen fog kinézni [AppVerifier Read-Only Halomlap (4k)] [A teszt alatt lévő alkalmazás által kért memória mennyisége] vagy ehhez hasonló [Az alkalmazás által kért memória mennyisége a teszt alatt] [AppVerifier Read-Only Halomlap (4k)].
A halomellenőrzés a Backward tulajdonságtól függően egy védőlapot helyez el a foglalás elején vagy végén. Ha a hátramenet hamis (ami az alapértelmezett érték), akkor a kiosztás végén egy védőlapot helyez el, hogy elfogja a puffertúlcsordulásokat. Ha igaz értékre van állítva, a védelmi lap a lefoglalás elejére kerül, hogy elfogja a puffer alulcsordulásait.
A program által igényelt memória speciális címkékkel való kitöltésekor (a halom tulajdonságai között található 'Teljes' jelölőnégyzet kikapcsolásával engedélyezve), az AppVerifier ellenőrzi és figyelmeztet arra, amikor a memória felszabadul. A technika használata során az a fő probléma, hogy vannak olyan esetek, amikor a memória sérülése csak a memória felszabadításakor lesz észlelhető (a memóriablokk minimális mennyisége 8 bájt), így ha egy 3 bájtos változó vagy egy 5 bájtos túlcsordulás történik, akkor a rendszer nem észleli azonnal.
Alulcsordulási esemény esetén a rendszer megpróbál írni egy Read-Only lapra. Ez kivételt fog kiváltani. Vegye figyelembe, hogy ez a kivétel csak akkor fogható el, ha a célalkalmazást egy hibakereső alatt futtatják. Vegye figyelembe, hogy a teljes oldal halom mód is észleli ezeket a hibákat, mert padding+guard oldalakat használ. Azért használná a könnyű lapkészletet, ha a számítógép nem tudja elviselni a teljes lapkészlet magas memóriaigényét.
Memóriaigényes alkalmazások esetén, vagy ha az AppVerifier használata hosszú ideig szükséges (például stressztesztelés), jobb, ha a teljesítménycsökkenés miatt normál (könnyű) halomteszteket futtat a teljes mód helyett. Amikor azonban problémába ütközik, a további vizsgálathoz kapcsolja be a teljes lapokra vonatkozó heap funkciót.
Az egyéni memóriahalmokat használó alkalmazások (memóriahalom, amely megkerüli az operációs rendszer memóriahalom-megvalósítását) lehet, hogy nem használják ki teljes mértékben a page heap előnyeit, vagy működésképtelenné válhatnak, amikor az engedélyezve van.
Memóriahibák hibakeresése
A memória-ellenőrző hibakereső bővítménye
A virtuális tér műveleti naplója nyomon követi az összes olyan rutint, amely bármilyen módon módosítja egy folyamat virtuális területét. Ezek közé tartozik a VirtualAlloc, a VirtualFree, a MapViewOfFile és a UnmapViewOfFile.
A !avrf -vs Length bővítményparancs használatával megjelenítheti az utolsó több rekordot; A hossz a rekordok számát határozza meg.
A !avrf -vs -a Cím használatával megjelenítheti a megadott címet érintő összes virtuálistér-műveletet. Foglalás esetén elegendő, ha a cím szerepel a lefoglalt blokkban. Ingyenesen meg kell adni a régió elejének pontos címét.
A napló minden egyes bejegyzése esetében a következő információk jelennek meg:
- A hívott függvény
- A rutint meghívó szál szálazonosítója
- A hívásban érintett cím – ez az a cím, amelyet egy foglalási rutin adott vissza, vagy amelyet egy ingyenes rutinnak adott át
- A hívásban érintett régió mérete
- A memóriaművelet típusa (a AllocationType paraméter)
- A kért védelem típusa
- A hívás veremnyoma
Példák
A legutóbbi bejegyzések jelennek meg először.
Az alábbi példában a két legutóbbi bejegyzés jelenik meg:
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
A kimenetből látható, hogy a szál 0xB4 először kibontott egy lapot, majd kiadta a teljes virtuális régiót.
Itt látható a cím 0x4BB1000 befolyásoló összes művelet:
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
A kimenet elolvasásához ne feledje, hogy a bejegyzések a legutóbbival kezdődnek. Így ez a napló azt mutatja, hogy a szál 0xB4 lefoglalt egy nagy régiót, amelyben lekötött egy lapot. Később megszüntette a lapot, majd kiadta a teljes virtuális régiót.
Lásd még:
Application Verifier – Áttekintés
Application Verifier – Alkalmazások tesztelése
Application Verifier – Az Application Verifier tesztelése