Dela via


Pseudo-Register Syntax

Felsökningsprogrammet stöder flera pseudoregister som innehåller vissa värden.

Felsökningsprogrammet anger automatiska pseudoregister till vissa användbara värden. Användardefinierade pseudoregister är heltalsvariabler som du kan skriva till eller läsa.

Alla pseudoregister börjar med ett dollartecken ($). Om du använder MASM-syntax kan du lägga till ett vidtecken ( @ ) före dollartecknet. Det här '@'-tecknet anger för felsökaren att följande token är ett register eller pseudoregister, inte en symbol. Om du utelämnar vid-tecknet svarar felsökningsprogrammet långsammare eftersom det måste söka i hela symboltabellen.

Följande två kommandon genererar till exempel samma utdata, men det andra kommandot är snabbare.

0:000> ? $exp
Evaluate expression: 143 = 0000008f
0:000> ? @$exp
Evaluate expression: 143 = 0000008f

Om en symbol finns med samma namn som pseudoregistret måste du lägga till vid-tecknet.

Om du använder syntaxen för C++-uttryck krävs alltid vid -tecknet ( @ ).

Kommandot r (Registers) är ett undantag från den här regeln. Felsökningsprogrammet tolkar alltid sitt första argument som ett register eller pseudoregister. (En snabel-a krävs inte eller tillåts inte.) Om det finns ett andra argument för r-kommandot tolkas det enligt standarduttryckssyntaxen. Om standarduttryckssyntaxen är C++, måste du använda följande kommando för att kopiera pseudoregistret $t 2 till pseudoregistret $t 1 .

0:000> r $t1 = @$t2

Automatisk Pseudo-Registers

Felsökningsprogrammet anger automatiskt följande pseudoregister.

Pseudoregister Beskrivning

$ea

Den effektiva adressen för den senast utförda instruktionen. Om den här instruktionen inte har någon effektiv adress, visar felsökaren "Fel på register". Om den här instruktionen har två effektiva adresser visar felsökningsprogrammet den första adressen.

$ea 2

Den andra effektiva adressen för den senaste instruktionen som kördes. Om den här instruktionen inte har två effektiva adresser visar debuggern "Felaktigt registerfel".

$exp

Det sista uttrycket som utvärderades.

$ra

Returadressen som för närvarande finns på stacken.

Den här adressen är särskilt användbar i exekveringskommandon. Till exempel fortsätter g @$ra tills returadressen hittas (även om gu (Go Up) är ett mer exakt och effektivt sätt att lämna den aktuella funktionen).

$ip

Instruktionspekarsregistret.

x86-baserade processorer: Samma som eip. Itaniumbaserade processorer: Relaterat till iip. (Mer information finns i kommentaren efter den här tabellen.) x64-baserade processorer: Samma som rip.

$eventip

Instruktionspekaren vid tidpunkten för den aktuella händelsen. Den här pekaren matchar vanligtvis $ip, såvida du inte har bytt tråd eller ändrat instruktionspekarens värde manuellt.

$previp

Instruktionspekaren vid tidpunkten för föregående händelse. (Inbrytning i felsökningsprogrammet räknas som en händelse.)

$relip

En instruktionspekare som är relaterad till den aktuella händelsen. När du spårar grenen är den här pekaren pekaren till grenkällan.

$scopeip

Instruktionspekaren för den aktuella lokala kontexten (kallas även omfånget).

$exentry

Adressen till startpunkten för den första körbara filen för den aktuella processen.

$retreg

Det primära returvärdesregistret.

x86-baserade processorer: Samma som eax. Itaniumbaserade processorer: Samma som ret0. x64-baserade processorer: Samma som rax.

$retreg 64

Det primära returvärdet registreras i 64-bitarsformat.

x86-processor: Samma som edx:eax-paret .

$csp

Den aktuella pekaren för anropsstacken. Den här pekaren är det register som är mest representativt för anropsstackens djup.

x86-baserade processorer: Samma som esp. Itaniumbaserade processorer: Samma som bsp. x64-baserade processorer: Samma som rsp.

$p

Värdet som kommandot last d* (Display Memory) skrev ut.

$proc

Adressen till den aktuella processen (dvs. adressen till EPROCESS-blocket).

$thread

Adressen till den aktuella tråden. I kernellägesfelsökning är den här adressen adressen till ETHREAD-blocket. I felsökning i användarläge är den här adressen adressen till trådmiljöblocket (TEB).

$peb

Adressen till processmiljöblocket (PEB) för den aktuella processen.

$teb

Adressen till trådmiljöblocket (TEB) för den aktuella tråden.

$tpid

Process-ID (PID) för den process som äger den aktuella tråden.

$tid

Tråd-ID:t för den aktuella tråden.

$dtid

$dpid

$dsid

$bpnummer

Adressen till motsvarande brytpunkt. Till exempel refererar $bp 3 (eller $bp 03) till brytpunkten vars brytpunkts-ID är 3. Tal är alltid ett decimaltal. Om ingen brytpunkt har ett ID för Tal utvärderas $bpTal till noll. Mer information om brytpunkter finns i Använda brytpunkter.

$frame

Det aktuella bildindexet. Det här indexet är samma ramnummer som kommandot .frame (Ange lokal kontext) använder.

$dbgtime

Den aktuella tiden, enligt den dator som felsökningsprogrammet körs på.

$callret

Returvärdet för den senaste funktionen som .call (Call Function) anropade eller som används i ett .fnret /s-kommando . Datatypen för $callret är datatypen för det här returvärdet.

$extret

$extin

$clrex

$lastclrex

Endast hanterad felsökning: Adressen till det senast påträffade CLR-undantagsobjektet (common language runtime).

$ptrsize

Storleken på en pekare. I kernelläge är den här storleken pekarstorleken på måldatorn.

$pagesize

Antalet byte på en sida med minne. I kernelläge är den här storleken sidstorleken på måldatorn.

$pcr

$pcrb

$argreg

$exr_chance

Sannolikheten för den aktuella undantagsposten.

$exr_code

Undantagskoden för den aktuella undantagsposten.

$exr_numparams

Antalet parametrar i den aktuella undantagsposten.

$exr_param0

Värdet för Parameter 0 i den aktuella undantagsregistreringen.

$exr_param1

Värdet för Parameter 1 i den aktuella undantagsposten.

$exr_param2

Värdet för Parameter 2 i den aktuella undantagsposten.

$exr_param3

Värdet för Parameter 3 i den aktuella undantagsposten.

$exr_param4

Värdet för Parameter 4 i det aktuella undantagsrekordet.

$exr_param5

Värdet för Parameter 5 i den aktuella undantagsposten.

$exr_param6

Värdet för Parameter 6 i den aktuella undantagsposten.

$exr_param7

Värdet för Parameter 7 i den aktuella undantagsposten.

$exr_param8

Värdet för Parameter 8 i den aktuella undantagsposten.

$exr_param9

Värdet för Parameter 9 i den aktuella undantagsposten.

$exr_param10

Värdet för Parameter 10 i den aktuella undantagsposten.

$exr_param11

Värdet för Parameter 11 i den aktuella undantagsposten.

$exr_param12

Värdet för Parameter 12 i den aktuella undantagsposten.

$exr_param13

Värdet för Parameter 13 i den aktuella undantagsposten.

$exr_param14

Värdet för Parameter 14 i den aktuella undantagsposten.

$bug_code

Om en felkontroll har inträffat är det här felkoden. Gäller för live kernel-läge felsökning och kernelkraschdumpar.

$bug_param1

Om en buggkontroll har inträffat är det här värdet för Parameter 1. Gäller för felsökning i live-kernelläge och kernelkraschdumpar.

$bug_param2

Om en buggkontroll har inträffat är det här värdet för Parameter 2. Gäller för felsökning i live-kärnläge och kärnkraschanalyser.

$bug_param3

Om en buggkontroll har inträffat är det här värdet för Parameter 3. Gäller för felsökning i live-kernelläge och kernelkraschdumpar.

$bug_param4

Om en buggkontroll har inträffat är det här värdet för Parameter 4. Gäller för felsökning i live-kärnläge och kärnkraschdumpar.

Vissa av dessa pseudoregister kanske inte är tillgängliga i vissa felsökningsscenarier. Du kan till exempel inte använda $peb, $tid och $tpid när du felsöker en minidump i användarläge eller vissa dumpfiler i kernelläge. Det kommer att finnas situationer där du kan lära dig trådinformation från ~ (trådstatus) men inte från $tid. Du kan inte använda $previp pseudoregister för den första felsökningshändelsen. Du kan inte använda pseudoregistret $relip om du inte spårar förgreningar. Om du använder ett otillgängligt pseudoregister uppstår ett syntaxfel.

Ett pseudoregister som innehåller adressen för en struktur – till exempel $thread, $proc, $teb, $peb och $lastclrex – utvärderas enligt rätt datatyp i utvärderingsverktyget för C++-uttryck, men inte i MASM-uttrycksutvärderingen. Kommandot ? $teb visar teb-adressen, medan kommandot ?? @$teb visar hela TEB-strukturen. Mer information finns i Utvärdera uttryck.

På en Itanium-baserad processor är iip-registret bundlejusterat, vilket innebär att det pekar på plats 0 i paketet som innehåller den aktuella instruktionen, även om en annan plats utförs. Så iip är inte den fullständiga instruktionspekaren. $ip-pseudoregistret är den faktiska instruktionspekaren, inklusive bunten och platsen. De andra pseudoregister som innehåller adresspekare ($ra, $retreg, $eventip, $previp, $relip och $exentry) har samma struktur som $ip på alla processorer.

Du kan använda r-kommandot för att ändra värdet för $ip. Den här ändringen ändrar också automatiskt motsvarande register. När körningen återupptas sker det vid den nya instruktionspekarens adress. Det här registret är det enda automatiska pseudoregistret som du kan ändra manuellt.

Obs I MASM-syntax kan du indikera $ip pseudoregister med en punkt ( . ). Du lägger inte till ett vidtecken (@) före den här perioden och använder inte perioden som den första parametern för r-kommandot . Den här syntaxen tillåts inte i ett C++-uttryck.

Automatiska pseudoregister liknar automatiska alias. Men du kan använda automatiska alias tillsammans med aliasrelaterade token (till exempel ${ }), och du kan inte använda pseudoregister med sådana token.

User-Defined Pseudo-Registers

Det finns 20 användardefinierade pseudoregister ($t 0, $t 1, ..., $t 19). Dessa pseudoregister är variabler som du kan läsa och skriva via felsökningsprogrammet. Du kan lagra alla heltalsvärden i dessa pseudoregister. De kan vara särskilt användbara som loopvariabler.

Om du vill skriva till ett av dessa pseudoregister använder du kommandot r (Registers), som i följande exempel visas.

0:000> r $t0 = 7
0:000> r $t1 = 128*poi(MyVar)

Precis som alla pseudoregister kan du använda det användardefinierade pseudoregistret i valfritt uttryck, vilket visas i följande exempel.

0:000> bp $t3 
0:000> bp @$t4 
0:000> ?? @$t1 + 4*@$t2 

Ett pseudoregister skrivs alltid som ett heltal, såvida du inte använder växeln ? tillsammans med r-kommandot . Om du använder den här växeln antar pseudoregistret typen av vad som tilldelas den. Följande kommando tilldelar till exempel typen UNICODE_STRING** och värdet 0x0012FFBC till $t 15.

0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc

Användardefinierade pseudoregister använder noll som standardvärde när felsökningsprogrammet startas.

Obs Aliaserna $u0, $u1, ..., $u9 är inte pseudoregister, trots deras liknande utseende. Mer information om dessa alias finns i Använda alias.

exempel

I följande exempel anges en brytpunkt som slås varje gång den aktuella tråden anropar NtOpenFile. Men den här brytpunkten uppnås inte när andra trådar anropar NtOpenFile.

kd> bp /t @$thread nt!ntopenfile

exempel

I följande exempel körs ett kommando tills registret innehåller ett angivet värde. Placera först följande kod för villkorsstyrd stegning i en skriptfil med namnet "eaxstep".

.if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" }

Utfärda sedan följande kommando.

t "$<eaxstep"

Felsökningsprogrammet utför ett steg och kör sedan kommandot. I det här fallet kör felsökningsprogrammet skriptet, som antingen visar 1234 eller upprepar processen.