Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il debugger supporta diversi pseudoregistri che contengono determinati valori.
Il debugger imposta i pseudoregistri automatici su determinati valori utili. Gli pseudoregistri definiti dall'utente sono variabili integer che è possibile scrivere o leggere.
Tutti i pseudoregistri iniziano con un segno di dollaro ($). Se si usa la sintassi MASM, è possibile aggiungere una chiocciola ( @ ) prima del segno del dollaro. Questo segno indica al debugger che il token seguente è un registro o pseudoregistro, non un simbolo. Se si omette la chiocciola, il debugger risponde più lentamente, perché deve cercare l'intera tabella dei simboli.
Ad esempio, i due comandi seguenti producono lo stesso output, ma il secondo comando è più veloce.
0:000> ? $exp
Evaluate expression: 143 = 0000008f
0:000> ? @$exp
Evaluate expression: 143 = 0000008f
Se esiste un simbolo con lo stesso nome dello pseudoregistro, è necessario aggiungere il simbolo della chiocciola.
Se si usa la sintassi dell'espressione C++, il simbolo at ( @ ) è sempre obbligatorio.
Il comando r (Registers) è un'eccezione a questa regola. Il debugger interpreta sempre il primo argomento come registro o pseudoregistro. (Non è richiesto o consentito un simbolo di accesso). Se è presente un secondo argomento per il comando r , viene interpretato in base alla sintassi dell'espressione predefinita. Se la sintassi dell'espressione predefinita è C++, è necessario usare il comando seguente per copiare lo pseudoregistro $t 2 nello pseudoregistro $t 1 .
0:000> r $t1 = @$t2
Pseudo-Registers automatico
Il debugger imposta automaticamente gli pseudoregistri seguenti.
| Pseudoregistro | Descrizione |
|---|---|
$ea |
Indirizzo effettivo dell'ultima istruzione eseguita. Se questa istruzione non ha un indirizzo effettivo, il debugger visualizza l'errore "Errore registro non valido". Se questa istruzione ha due indirizzi effettivi, il debugger visualizza il primo indirizzo. |
$ea 2 |
Secondo indirizzo effettivo dell'ultima istruzione eseguita. Se questa istruzione non dispone di due indirizzi effettivi, nel debugger viene visualizzato l'errore "Errore di registrazione non valida". |
$exp |
Ultima espressione valutata. |
$ra |
L'indirizzo di ritorno che è attualmente nello stack. Questo indirizzo è particolarmente utile nei comandi di esecuzione. Ad esempio, g @$ra continua fino a quando non viene trovato l'indirizzo restituito (anche se gu (Go Up) è un modo più preciso di "uscire" dalla funzione corrente. |
$ip |
Registro del puntatore all'istruzione. Processori basati su x86: Uguale a eip. Processori basati su Itanium: Correlato a iip. Per altre informazioni, vedere la nota seguente. Processori basati su x64: Uguale a rip. |
$eventip |
Puntatore all'istruzione al momento dell'evento corrente. Questo puntatore corrisponde in genere $ip, a meno che non si sia cambiato thread o sia stato modificato manualmente il valore del puntatore all'istruzione. |
$previp |
Puntatore all'istruzione al momento dell'evento precedente. L'interruzione nel debugger viene conteggiata come evento. |
$relip |
Puntatore all'istruzione relativo all'evento corrente. Quando si esegue la tracciatura dei rami, questo puntatore è il puntatore alla sorgente del ramo. |
$scopeip |
Puntatore all'istruzione per il contesto locale corrente (noto anche come ambito). |
$exentry |
Indirizzo del punto di ingresso del primo eseguibile del processo corrente. |
$retreg |
Registro principale del valore restituito. Processori basati su x86: Uguale a eax. Processori basati su Itanium: Uguale a ret0. Processori basati su x64: Uguale a rax. |
$retreg 64 |
Registro del valore restituito primario, in formato a 64 bit. Processore x86: Uguale alla coppia edx:eax . |
$csp |
Puntatore dello stack di chiamate corrente. Questo puntatore è il registro più rappresentativo della profondità dello stack di chiamate. Processori basati su x86: Uguale a esp. Processori basati su Itanium: Uguale a bsp. Processori basati su x64: Uguale a rsp. |
$p |
Il valore stampato dall'ultimo comando d* (Display Memory). |
$proc |
Indirizzo del processo corrente, ovvero l'indirizzo del blocco EPROCESS. |
$thread |
Indirizzo del thread corrente. Nel debug in modalità kernel, questo indirizzo è l'indirizzo del blocco ETHREAD. Nel debug in modalità utente, questo indirizzo è l'indirizzo del blocco di ambiente thread (TEB). |
$peb |
Indirizzo del blocco di ambiente del processo (PEB) del processo corrente. |
$teb |
Indirizzo del blocco di ambiente del thread (TEB) del thread corrente. |
$tpid |
ID processo (PID) per il processo proprietario del thread corrente. |
$tid |
ID del thread per il thread attuale. |
$dtid |
|
$dpid |
|
$dsid |
|
numero $bp |
Indirizzo del punto di interruzione corrispondente. Ad esempio, $bp 3 (o $bp 03) fa riferimento al punto di interruzione il cui ID punto di interruzione è 3. Il numero è sempre un numero decimale. Se nessun punto di interruzione ha un ID Number, $bpNumber restituisce zero. Per altre informazioni sui punti di interruzione, vedere Uso dei punti di interruzione. |
$frame |
Indice del frame corrente. Questo indice è lo stesso numero di frame usato dal comando .frame (Set Local Context). |
$dbgtime |
Ora corrente, in base al computer in cui è in esecuzione il debugger. |
$callret |
Il valore restituito della funzione chiamata per ultima tramite .call (Call Function) oppure utilizzato in un comando .fnret /s. Il tipo di dati di questo valore restituito è lo stesso tipo di dati di $callret. |
$extret |
|
$extin |
|
$clrex |
|
$lastclrex |
Solo debug gestito: Indirizzo dell'ultimo oggetto di eccezione del Common Language Runtime (CLR) incontrato. |
$ptrsize |
Dimensione di un puntatore. In modalità kernel, questa dimensione è la dimensione del puntatore nel computer di destinazione. |
$pagesize |
Numero di byte in una pagina di memoria. In modalità kernel, queste dimensioni sono le dimensioni della pagina nel computer di destinazione. |
$pcr |
|
$pcrb |
|
$argreg |
|
$exr_chance |
Probabilità del record di eccezione corrente. |
$exr_code |
Il codice di eccezione per il record di eccezione corrente. |
$exr_numparams |
Il numero di parametri del record di eccezione corrente. |
$exr_param0 |
Valore del parametro 0 nel record di eccezione corrente. |
$exr_param1 |
Valore del parametro 1 nel record di eccezione corrente. |
$exr_param2 |
Valore del parametro 2 nel record di eccezione corrente. |
$exr_param3 |
Valore del parametro 3 nel record di eccezione corrente. |
$exr_param4 |
Valore del parametro 4 nel record di eccezione corrente. |
$exr_param5 |
Valore del parametro 5 nel record di eccezione corrente. |
$exr_param6 |
Valore del parametro 6 nel record di eccezione corrente. |
$exr_param7 |
Valore del parametro 7 nel record di eccezione corrente. |
$exr_param8 |
Valore del parametro 8 nel record di eccezione corrente. |
$exr_param9 |
Valore del parametro 9 nel record di eccezione corrente. |
$exr_param10 |
Valore del parametro 10 nel record di eccezione corrente. |
$exr_param11 |
Il valore del parametro 11 nel record di eccezione corrente. |
$exr_param12 |
Il valore del parametro 12 nel record di eccezione corrente. |
$exr_param13 |
Valore del parametro 13 nel record di eccezione corrente. |
$exr_param14 |
Il valore del parametro 14 nel record di eccezione corrente. |
$bug_code |
Se si è verificata una verifica di errore, questo è il codice di errore. Si applica al debug in modalità kernel in tempo reale e ai dump di arresto anomalo del kernel. |
$bug_param1 |
Se si è verificato un controllo di bug, questo è il valore del parametro 1. Si applica al debug in modalità kernel in tempo reale e ai dump di arresto anomalo del kernel. |
$bug_param2 |
Se si è verificato un controllo di bug, questo è il valore del parametro 2. Si applica al debug in modalità kernel in tempo reale e ai dump di arresto anomalo del kernel. |
$bug_param3 |
Se si è verificato un controllo di bug, questo è il valore del parametro 3. Si applica al debug in modalità kernel in tempo reale e ai dump di arresto anomalo del kernel. |
$bug_param4 |
Se si è verificato un controllo di bug, questo è il valore del parametro 4. Si applica al debug in modalità kernel in tempo reale e ai dump di arresto anomalo del kernel. |
Alcuni di questi pseudoregistri potrebbero non essere disponibili in determinati scenari di debug. Ad esempio, non è possibile usare $peb, $tid e $tpid quando si esegue il debug di un minidump in modalità utente o di determinati file di dump in modalità kernel. Ci saranno situazioni in cui è possibile apprendere le informazioni sul thread da ~ (Stato thread) ma non da $tid. Non è possibile utilizzare il $previp pseudoregistro nel primo evento del debugger. Non è possibile utilizzare il $relip pseudoregistro a meno che non si stia eseguendo la tracciatura dei branch. Se si usa uno pseudoregistro non disponibile, si verifica un errore di sintassi.
Uno pseudoregistro che contiene l'indirizzo di una struttura, ad esempio $thread, $proc, $teb, $peb e $lastclrex , verrà valutato in base al tipo di dati appropriato nell'analizzatore di espressioni C++, ma non nell'analizzatore di espressioni MASM. Ad esempio, il comando ? $teb visualizza l'indirizzo del TEB, mentre il comando ?? @$teb visualizza l'intera struttura TEB. Per altre informazioni, vedere Valutazione delle espressioni.
In un processore basato su Itanium, il registro iip è allineato al bundle, il che significa che punta allo slot 0 nel bundle contenente l'istruzione corrente, anche se viene eseguito uno slot diverso. Quindi iip non è il puntatore completo dell'istruzione. Il pseudoregistro $ip rappresenta effettivamente il puntatore dell'istruzione, compreso il bundle e lo slot. Gli altri pseudoregistri che contengono puntatori agli indirizzi ($ra, $retreg, $eventip, $previp, $relip e $exentry) hanno la stessa struttura di $ip in tutti i processori.
È possibile usare il comando r per modificare il valore di $ip. Questa modifica cambia automaticamente anche il registro corrispondente. Quando l'esecuzione riprende, riprende all'indirizzo del nuovo puntatore di istruzione. Questo registro è l'unico pseudoregistro automatico che è possibile modificare manualmente.
Nota Nella sintassi MASM è possibile indicare il $ip pseudoregistro con un punto ( . ). Prima di questo periodo non si aggiunge un segno (@) e non si usa il punto come primo parametro del comando r . Questa sintassi non è consentita all'interno di un'espressione C++.
Gli pseudoregistri automatici sono simili agli alias automatici. Tuttavia, è possibile usare alias automatici insieme ai token correlati agli alias (ad esempio ${ }) e non è possibile usare pseudoregistri con tali token.
User-Defined Pseudo-Registers
Esistono 20 pseudoregistri definiti dall'utente ($t 0, $t 1, ..., $t 19). Questi pseudoregistri sono variabili che è possibile leggere e scrivere tramite il debugger. È possibile archiviare qualsiasi valore intero in questi pseudoregistri. Possono essere particolarmente utili come variabili di ciclo.
Per scrivere in uno di questi pseudoregistri, usare il comando r (Registers), come illustrato nell'esempio seguente.
0:000> r $t0 = 7
0:000> r $t1 = 128*poi(MyVar)
Analogamente a tutti i pseudoregistri, è possibile usare lo pseudoregistro definito dall'utente in qualsiasi espressione, come illustrato nell'esempio seguente.
0:000> bp $t3
0:000> bp @$t4
0:000> ?? @$t1 + 4*@$t2
Uno pseudoregistro viene sempre digitato come numero intero, a meno che non si usi l'opzione ? insieme al comando r . Se si usa questa opzione, lo pseudoregistro acquisisce il tipo di qualsiasi elemento assegnato. Ad esempio, il comando seguente assegna il tipo UNICODE_STRING** e il valore 0x0012FFBC a $t 15.
0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc
I pseudoregistri definiti dall'utente usano zero come valore predefinito all'avvio del debugger.
Nota Gli alias $u 0, $u 1, ..., $u 9 non sono pseudoregistri, nonostante l'aspetto simile. Per altre informazioni su questi alias, vedere Uso degli alias.
Esempio di
Nell'esempio seguente viene impostato un punto di interruzione raggiunto ogni volta che il thread corrente chiama NtOpenFile. Ma questo punto di interruzione non viene raggiunto quando altri thread chiamano NtOpenFile.
kd> bp /t @$thread nt!ntopenfile
Esempio di
Nell'esempio seguente viene eseguito un comando fino a quando il registro non contiene un valore specificato. Per prima cosa, aggiungere il codice seguente per il passaggio condizionale in un file di script denominato "eaxstep".
.if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" }
Eseguire quindi il comando seguente.
t "$<eaxstep"
Il debugger esegue un passaggio e quindi esegue il comando . In questo caso, il debugger esegue lo script, che visualizza 1234 o ripete il processo.