Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ladicí program podporuje několik pseudoregistrů, které obsahují určité hodnoty.
Ladicí program nastaví automatické pseudoregistry na určité užitečné hodnoty. Uživatelsky definované pseudoregistry jsou celočíselné proměnné, do které můžete zapisovat nebo číst.
Všechny pseudoregistry začínají znakem dolaru ($). Pokud používáte syntaxi MASM, můžete před znak dolaru přidat znak at ( @ ). Toto označení říká ladicímu programu, že následující token je registr nebo pseudoregistr, nikoli symbol. Pokud vynecháte zavináč, ladicí program reaguje pomaleji, protože musí prohledávat celou tabulku symbolů.
Například následující dva příkazy vytvoří stejný výstup, ale druhý příkaz je rychlejší.
0:000> ? $exp
Evaluate expression: 143 = 0000008f
0:000> ? @$exp
Evaluate expression: 143 = 0000008f
Pokud symbol existuje se stejným názvem jako pseudoregistr, musíte přidat znak zavináč (@).
Pokud používáte syntaxi výrazu C++, je vždy vyžadován znak at ( @ ).
Příkaz r (Registers) je výjimkou tohoto pravidla. Ladicí program vždy interpretuje svůj první argument jako registr nebo pseudoregistr. (Znak at není povinný nebo povolený.) Pokud je pro příkaz r druhý argument, interpretuje se podle výchozí syntaxe výrazu. Pokud je výchozí syntaxe výrazu C++, musíte pomocí následujícího příkazu zkopírovat pseudoregistr $t 2 do pseudoregistru $t 1 .
0:000> r $t1 = @$t2
Automatické Pseudo-Registers
Ladicí program automaticky nastaví následující pseudoregistry.
| Pseudo-registr | Popis |
|---|---|
$ea |
Platná adresa poslední instrukce, která byla provedena. Pokud tato instrukce nemá efektivní adresu, ladicí program zobrazí chybu špatného registru. Pokud má tato instrukce dvě efektivní adresy, zobrazí ladicí program první adresu. |
$ea 2 |
Druhá platná adresa poslední instrukce, která byla provedena. Pokud tato instrukce nemá dvě účinné adresy, ladicí program zobrazí chybu špatného registru. |
$exp |
Poslední výraz, který byl vyhodnocen. |
$ra |
Vrácená adresa, která je aktuálně v zásobníku. Tato adresa je zvlášť užitečná při provádění příkazů. Například g @$ra pokračuje, dokud se nenajde návratová adresa (i když gu (Přejít nahoru) je přesnější způsob "odkročování" aktuální funkce). |
$ip |
Registr instrukčního ukazatele. Procesory založené na platformě x86: Totéž jako eip. Procesory s procesorem Itanium: Souvisí s iip. (Další informace najdete v následující tabulce.) Procesory založené na platformě x64: To samé jako rip. |
$eventip |
Ukazatel instrukce v době aktuální události. Tento ukazatel obvykle odpovídá $ip, pokud jste přepnuli vlákna nebo ručně nezměnili hodnotu instrukčního ukazatele. |
$previp |
Instrukční ukazatel v době předchozí události. (Vstup do ladicího programu se počítá jako událost.) |
$relip |
Ukazatel instrukce, který souvisí s aktuální událostí. Při trasování větví je tento ukazatel ukazatelem na zdroj větve. |
$scopeip |
Ukazatel instrukce pro aktuální místní kontext (označovaný také jako obor). |
$exentry |
Adresa vstupního bodu prvního spustitelného souboru aktuálního procesu. |
$retreg |
Registr primární návratové hodnoty. Procesory založené na platformě x86: Totéž jako eax. Procesory založené na Itanium: Stejné jako ret0. Procesory založené na platformě x64: To samé jako rax. |
$retreg 64 |
Registr primární návratové hodnoty v 64bitovém formátu. Procesor x86: Stejné jako dvojice edx:eax . |
$csp |
Aktuální ukazatel zásobníku volání. Tento ukazatel je registr, který nejlépe vyjadřuje hloubku zásobníku volání. Procesory založené na platformě x86: To samé jako esp. Procesory s procesory s procesorem Itanium: Totéž jako bsp. Procesory založené na platformě x64: To samé jako rsp. |
$p |
Hodnota, kterou vytiskl poslední příkaz d* (Zobrazit paměť). |
$proc |
Adresa aktuálního procesu (tj. adresa bloku EPROCESS). |
$thread |
Adresa aktuálního vlákna. V ladění v režimu jádra je tato adresa adresou bloku ETHREAD. Při ladění v uživatelském režimu určuje tato adresa blok prostředí vlákna (TEB). |
$peb |
Adresa bloku prostředí procesu (PEB) aktuálního procesu. |
$teb |
Adresa bloku prostředí vlákna (TEB) aktuálního vlákna. |
$tpid |
ID procesu (PID) pro proces, který vlastní aktuální vlákno. |
$tid |
ID vlákna pro aktuální vlákno. |
$dtid |
|
$dpid |
|
$dsid |
|
$bpčíslo |
Adresa odpovídajícího přerušeného bodu. Například $bp 3 (nebo $bp 03) odkazuje na zarážku, jejíž ID zarážky je 3. Číslo je vždy desetinné číslo. Pokud žádný bod přerušení nemá ID Number, $bpNumber se vyhodnotí jako nula. Další informace o zarážkách viz Použití zarážek. |
$frame |
Aktuální index rámce. Tento index je stejné číslo rámce, jaké používá příkaz .frame (Nastavit místní kontext). |
$dbgtime |
Aktuální čas podle počítače, na kterém je ladicí program spuštěný. |
$callret |
Návratová hodnota poslední funkce, která volala .call (funkce volání) nebo která se používá v příkazu .fnret /s . Datový typ $callret je datový typ této návratové hodnoty. |
$extret |
|
$extin |
|
$clrex |
|
$lastclrex |
Pouze spravované ladění: Adresa posledního nalezeného objektu výjimky common language runtime (CLR). |
$ptrsize |
Velikost ukazatele V režimu jádra je tato velikost ukazatele na cílovém počítači. |
$pagesize |
Počet bajtů v jedné stránce paměti. V režimu jádra je tato velikost stránky v cílovém počítači. |
$pcr |
|
$pcrb |
|
$argreg |
|
$exr_chance |
Pravděpodobnost výskytu aktuálního záznamu výjimky. |
$exr_code |
Kód výjimky pro aktuální záznam výjimky. |
$exr_numparams |
Počet parametrů v aktuálním záznamu výjimky. |
$exr_param0 |
Hodnota parametru 0 v aktuálním záznamu výjimky. |
$exr_param1 |
Hodnota parametru 1 v aktuálním záznamu výjimky. |
$exr_param2 |
Hodnota parametru 2 v aktuálním záznamu výjimky. |
$exr_param3 |
Hodnota parametru 3 v aktuálním záznamu výjimky. |
$exr_param4 |
Hodnota parametru 4 v aktuálním záznamu výjimky. |
$exr_param5 |
Hodnota parametru 5 v aktuálním záznamu výjimky. |
$exr_param6 |
Hodnota parametru 6 v aktuálním záznamu výjimky. |
$exr_param7 |
Hodnota parametru 7 v aktuálním záznamu výjimky. |
$exr_param8 |
Hodnota parametru 8 v aktuálním záznamu výjimky. |
$exr_param9 |
Hodnota parametru 9 v aktuálním záznamu výjimky. |
$exr_param10 |
Hodnota parametru 10 v aktuálním záznamu výjimky. |
$exr_param11 |
Hodnota parametru 11 v aktuálním záznamu výjimky. |
$exr_param12 |
Hodnota parametru 12 v aktuálním záznamu výjimky. |
$exr_param13 |
Hodnota parametru 13 v aktuálním záznamu výjimky. |
$exr_param14 |
Hodnota parametru 14 v aktuálním záznamu výjimky. |
$bug_code |
Pokud došlo ke kontrole chyb, jedná se o kód chyby. Platí pro ladění režimu jádra v reálném čase a výpisy paměti jádra po havárii. |
$bug_param1 |
Pokud došlo ke kontrole chyb, jedná se o hodnotu parametru 1. Platí pro ladění v živém režimu jádra a výpisy stavu systému jádra. |
$bug_param2 |
Pokud došlo ke kontrole chyb, jedná se o hodnotu parametru 2. Platí pro ladění v živém režimu jádra a výpisy stavu systému jádra. |
$bug_param3 |
Pokud došlo ke kontrole chyb, jedná se o hodnotu parametru 3. Platí pro ladění jádra v reálném čase a výpisy stavu systémových chyb jádra. |
$bug_param4 |
Pokud došlo ke kontrole chyb, jedná se o hodnotu parametru 4. Platí pro ladění v živém režimu jádra a výpisy stavu systému jádra. |
Některé z těchto pseudoregistrů nemusí být v určitých scénářích ladění dostupné. Například nemůžete použít $peb, $tid a $tpid při ladění minidump uživatelského režimu nebo určitých souborů s výpisem stavu režimu jádra. Vyskytují se situace, kdy můžete zjistit informace o vlákně z ~ (Stav vlákna), ale ne z $tid. U první události ladicího programu nelze použít pseudoregistr $previp. Nemůžete použít $relip pseudoregistr, pokud nezapínáte trasování větví. Pokud použijete nedostupný pseudoregistr, dojde k chybě syntaxe.
Pseudoregistr, který obsahuje adresu struktury – například $thread, $proc, $teb, $peb a $lastclrex – se vyhodnotí podle správného datového typu v vyhodnocovače výrazů C++, ale ne v vyhodnocovače výrazů MASM. Například příkaz ? $teb zobrazí adresu TEB, zatímco příkaz ?? @$teb zobrazí celou strukturu TEB. Další informace naleznete v tématu Vyhodnocení výrazů.
Na procesoru s architekturou Itanium je registr iipzarovnaný s balíčkem, což znamená, že odkazuje na slot 0 v balíčku obsahujícím aktuální instrukci, i když se provádí jiný slot. Takže iip není úplný instrukční ukazatel. Pseudoregistr $ip je skutečný ukazatel instrukce, včetně svazku a slotu. Ostatní pseudoregistry, které obsahují ukazatele adres ($ra, $retreg, $eventip, $previp, $relip a $exentry) mají stejnou strukturu jako $ip na všech procesorech.
Pomocí příkazu r můžete změnit hodnotu $ip. Tato změna také automaticky změní odpovídající registr. Když se provádění obnoví, obnoví se na nové adrese ukazatele instrukce. Tento registr je jediný automatický pseudoregistr, který můžete změnit ručně.
Poznámka V syntaxi MASM můžete označit $ip pseudoregistr s tečkou ( . ). Před tímto obdobím nepřidáte znak at (@) a tečku nepoužívejte jako první parametr příkazu r . Tato syntaxe není povolena v rámci výrazu jazyka C++.
Automatické pseudoregistry se podobají automatickým aliasům. Můžete ale použít automatické aliasy společně s tokeny souvisejícími s aliasy (například ${ }) a u těchto tokenů nemůžete používat pseudoregistry.
User-Defined Pseudo-Registers
Existuje 20 pseudoregistrů definovaných uživatelem ($t 0, $t 1, ..., $t 19). Tyto pseudo registry jsou proměnné, které můžete číst a zapisovat prostřednictvím ladicího programu. Do těchto pseudoregistrů můžete uložit libovolnou celočíselnou hodnotu. Mohou být zvlášť užitečné jako smyčkové proměnné.
K zápisu do jednoho z těchto pseudoregistrů použijte příkaz r (Registers), jak ukazuje následující příklad.
0:000> r $t0 = 7
0:000> r $t1 = 128*poi(MyVar)
Stejně jako všechny pseudoregistry můžete použít uživatelem definovaný pseudoregistr v libovolném výrazu, jak ukazuje následující příklad.
0:000> bp $t3
0:000> bp @$t4
0:000> ?? @$t1 + 4*@$t2
Pseudoregistr je vždy zadán jako celé číslo, pokud nepoužíváte přepínač ? společně s příkazem r . Pokud použijete tento přepínač, pseudoregistr získá typ všeho, co je k němu přiřazeno. Například následující příkaz přiřadí typ UNICODE_STRING** a 0x0012FFBC hodnotu $t 15.
0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc
Pseudoregistry definované uživatelem používají při spuštění ladicího programu nulu jako výchozí hodnotu.
Poznámka Aliasy $u 0, $u 1, ..., $u 9 nejsou pseudoregistry, navzdory jejich podobnému vzhledu. Další informace o těchto aliasech najdete v tématu Použití aliasů.
Příklad
Následující příklad nastaví bod přerušení, který je vyvolán pokaždé, když aktuální vlákno volá NtOpenFile. Tato zarážka se však nenarazí, když jiná vlákna volají NtOpenFile.
kd> bp /t @$thread nt!ntopenfile
Příklad
Následující příklad spustí příkaz, dokud registr obsahuje zadanou hodnotu. Nejprve vložte následující kód pro podmíněné krokování do souboru skriptu s názvem "eaxstep".
.if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" }
Pak spusťte následující příkaz.
t "$<eaxstep"
Ladicí program provede krok a potom spustí váš příkaz. V tomto případě ladicí program spustí skript, který buď zobrazí hodnotu 1234 , nebo tento proces zopakuje.