Share via


Sintaxis de Pseudo-Register

El depurador admite varios pseudo-registros que contienen determinados valores.

El depurador establece los pseudo-registros automáticos en determinados valores útiles. Los pseudo-registros definidos por el usuario son variables enteras que se pueden escribir en o leer.

Todos los pseudo-registros comienzan con un signo de dólar ($). Si usa la sintaxis de MASM, puede agregar un signo en signo ( @ ) antes del signo de dólar. Esto en signo indica al depurador que el siguiente token es un registro o pseudo-registro, no un símbolo. Si omite el signo, el depurador responde más lentamente, ya que tiene que buscar en toda la tabla de símbolos.

Por ejemplo, los dos comandos siguientes generan la misma salida, pero el segundo comando es más rápido.

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

Si existe un símbolo con el mismo nombre que el pseudo-registro, debe agregar el signo at.

Si usa la sintaxis de expresión de C++, siempre se requiere el signo at ( @ ).

El comando r (Registers) es una excepción a esta regla. El depurador siempre interpreta su primer argumento como registro o pseudo-registro. (No se requiere ni permite un signo). Si hay un segundo argumento para el comando r , se interpreta según la sintaxis de expresión predeterminada. Si la sintaxis de expresión predeterminada es C++, debe usar el siguiente comando para copiar el pseudo-registro de $t 2 en el pseudo-register de $t 1 .

0:000> r $t1 = @$t2

Pseudo-Registers automática

El depurador establece automáticamente los pseudo-registros siguientes.

Pseudo-registro Descripción

$ea

Dirección efectiva de la última instrucción que se ejecutó. Si esta instrucción no tiene una dirección efectiva, el depurador muestra "Error de registro incorrecto". Si esta instrucción tiene dos direcciones eficaces, el depurador muestra la primera dirección.

$ea 2

Segunda dirección efectiva de la última instrucción que se ejecutó. Si esta instrucción no tiene dos direcciones eficaces, el depurador muestra "Error de registro incorrecto".

$exp

Última expresión que se evaluó.

$ra

Dirección de devolución que se encuentra actualmente en la pila.

Esta dirección es especialmente útil en los comandos de ejecución. Por ejemplo, g @$ra continúa hasta que se encuentra la dirección de retorno (aunque gu (Ir arriba) es una manera más precisa de "salir" de la función actual).

$ip

Registro del puntero de instrucción.

Procesadores basados en x86: Igual que eip. Procesadores basados en Itanium: Relacionado con iip. (Para obtener más información, consulte la nota siguiente a esta tabla). Procesadores basados en x64: Lo mismo que rasgar.

$eventip

Puntero de instrucción en el momento del evento actual. Este puntero suele coincidir con $ip, a menos que cambie los subprocesos o cambie manualmente el valor del puntero de instrucción.

$previp

Puntero de instrucción en el momento del evento anterior. (La separación en el depurador cuenta como un evento).

$relip

Puntero de instrucción relacionado con el evento actual. Cuando se realiza el seguimiento de ramas, este puntero es el puntero al origen de la rama.

$scopeip

Puntero de instrucción para el contexto local actual (también conocido como ámbito).

$exentry

Dirección del punto de entrada del primer ejecutable del proceso actual.

$retreg

Registro del valor devuelto principal.

Procesadores basados en x86: Igual que eax. Procesadores basados en Itanium: Igual que ret0. Procesadores basados en x64: Igual que rax.

$retreg 64

Registro del valor devuelto principal, en formato de 64 bits.

Procesador x86: Igual que el par edx:eax .

$csp

Puntero de pila de llamadas actual. Este puntero es el registro más representativo de la profundidad de la pila de llamadas.

Procesadores basados en x86: Igual que esp. Procesadores basados en Itanium: Igual que bsp. Procesadores basados en x64: Igual que rsp.

$p

Valor que imprimió el último comando d* (Memoria para mostrar ).

$proc

Dirección del proceso actual (es decir, la dirección del bloque EPROCESS).

$thread

Dirección del subproceso actual. En la depuración en modo kernel, esta dirección es la dirección del bloque ETHREAD. En la depuración en modo de usuario, esta dirección es la dirección del bloque de entorno de subprocesos (TEB).

$peb

Dirección del bloque de entorno de proceso (PEB) del proceso actual.

$teb

Dirección del bloque de entorno de subprocesos (TEB) del subproceso actual.

$tpid

Identificador de proceso (PID) del proceso que posee el subproceso actual.

$tid

Identificador del subproceso del subproceso actual.

$dtid

$dpid

$dsid

número de $bp

Dirección del punto de interrupción correspondiente. Por ejemplo, $bp 3 (o $bp 03) hace referencia al punto de interrupción cuyo identificador de punto de interrupción es 3. Number siempre es un número decimal. Si ningún punto de interrupción tiene un identificador de Number, $bpNumber se evalúa como cero. Para obtener más información sobre los puntos de interrupción, vea Uso de puntos de interrupción.

$frame

Índice de marco actual. Este índice es el mismo número de fotograma que usa el comando .frame (Establecer contexto local ).

$dbgtime

La hora actual, según el equipo en el que se ejecuta el depurador.

$callret

Valor devuelto de la última función a la que llamó .call (Call Function) o que se usa en un comando .fnret /s . El tipo de datos de $callret es el tipo de datos de este valor devuelto.

$extret

$extin

$clrex

$lastclrex

Solo depuración administrada: Dirección del último objeto de excepción de Common Language Runtime (CLR).

$ptrsize

Tamaño de un puntero. En el modo kernel, este tamaño es el tamaño del puntero en el equipo de destino.

$pagesize

Número de bytes en una página de memoria. En el modo kernel, este tamaño es el tamaño de página en el equipo de destino.

$pcr

$pcrb

$argreg

$exr_chance

Posibilidad del registro de excepción actual.

$exr_code

Código de excepción del registro de excepción actual.

$exr_numparams

Número de parámetros del registro de excepción actual.

$exr_param0

Valor del parámetro 0 en el registro de excepción actual.

$exr_param1

Valor del parámetro 1 en el registro de excepción actual.

$exr_param2

Valor del parámetro 2 en el registro de excepción actual.

$exr_param3

Valor del parámetro 3 en el registro de excepción actual.

$exr_param4

Valor del parámetro 4 en el registro de excepción actual.

$exr_param5

Valor del parámetro 5 en el registro de excepción actual.

$exr_param6

Valor del parámetro 6 en el registro de excepción actual.

$exr_param7

Valor del parámetro 7 en el registro de excepción actual.

$exr_param8

Valor del parámetro 8 en el registro de excepción actual.

$exr_param9

Valor del parámetro 9 en el registro de excepción actual.

$exr_param10

Valor del parámetro 10 en el registro de excepción actual.

$exr_param11

Valor del parámetro 11 en el registro de excepción actual.

$exr_param12

Valor del parámetro 12 en el registro de excepción actual.

$exr_param13

Valor del parámetro 13 en el registro de excepción actual.

$exr_param14

Valor del parámetro 14 en el registro de excepción actual.

$bug_code

Si se ha producido una comprobación de errores, este es el código de error. Se aplica a la depuración en modo kernel activo y a los volcados de memoria del kernel.

$bug_param1

Si se ha producido una comprobación de errores, este es el valor del parámetro 1. Se aplica a la depuración en modo kernel activo y a los volcados de memoria del kernel.

$bug_param2

Si se ha producido una comprobación de errores, este es el valor del parámetro 2. Se aplica a la depuración en modo kernel activo y a los volcados de memoria del kernel.

$bug_param3

Si se ha producido una comprobación de errores, este es el valor del parámetro 3. Se aplica a la depuración en modo kernel activo y a los volcados de memoria del kernel.

$bug_param4

Si se ha producido una comprobación de errores, este es el valor del parámetro 4. Se aplica a la depuración en modo kernel activo y a los volcados de memoria del kernel.

Es posible que algunos de estos pseudo-registros no estén disponibles en determinados escenarios de depuración. Por ejemplo, no puede usar $peb, $tid y $tpid al depurar un minivolcado en modo de usuario o determinados archivos de volcado de modo kernel. Habrá situaciones en las que puede aprender información de subprocesos de ~ (estado del subproceso), pero no de $tid. No se puede usar el $previp pseudo-register en el primer evento del depurador. No puede usar el $relip pseudo-register a menos que sea el seguimiento de ramas. Si usa un pseudo-registro no disponible, se produce un error de sintaxis.

Un pseudo-registro que contiene la dirección de una estructura (como $thread, $proc, $teb, $peb y $lastclrex ) se evaluará según el tipo de datos adecuado en el evaluador de expresiones de C++, pero no en el evaluador de expresiones masm. Por ejemplo, el comando ? $teb muestra la dirección del TEB, mientras que el comando ?? @$teb muestra toda la estructura TEB. Para obtener más información, vea Evaluación de expresiones.

En un procesador basado en Itanium, el registro iip está alineado con agrupación, lo que significa que apunta a la ranura 0 del lote que contiene la instrucción actual, incluso si se ejecuta una ranura diferente. Por lo tanto , iip no es el puntero de instrucción completa. El $ip pseudo-register es el puntero de instrucción real, incluido el lote y la ranura. Los demás pseudo-registros que contienen punteros de dirección ($ra, $retreg, $eventip, $previp, $relip y $exentry) tienen la misma estructura que $ip en todos los procesadores.

Puede usar el comando r para cambiar el valor de $ip. Este cambio también cambia automáticamente el registro correspondiente. Cuando se reanuda la ejecución, se reanuda en la nueva dirección del puntero de instrucción. Este registro es el único pseudo-registro automático que puede cambiar manualmente.

Nota En la sintaxis de MASM, puede indicar el $ip pseudo-register con un punto ( . ). No agregue un signo a signo (@) antes de este período y no use el punto como primer parámetro del comando r . Esta sintaxis no se permite dentro de una expresión de C++.

Los pseudo-registros automáticos son similares a los alias automáticos. Sin embargo, puede usar alias automáticos junto con tokens relacionados con alias (como ${ }) y no puede usar pseudo-registros con dichos tokens.

Pseudo-Registers definidas por el usuario

Hay 20 pseudo-registros definidos por el usuario ($t 0, $t 1, ..., $t 19). Estos pseudo-registro son variables que se pueden leer y escribir a través del depurador. Puede almacenar cualquier valor entero en estos pseudo-registros. Pueden ser especialmente útiles como variables de bucle.

Para escribir en uno de estos pseudo-registros, use el comando r (Registers), como se muestra en el ejemplo siguiente.

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

Al igual que todos los pseudo-registros, puede usar el pseudo-registro definido por el usuario en cualquier expresión, como se muestra en el ejemplo siguiente.

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

Un pseudo-registro siempre se escribe como un entero, a menos que use el modificador ? junto con el comando r . Si usa este modificador, el pseudo-registro adquiere el tipo de lo que se le asigna. Por ejemplo, el siguiente comando asigna el tipo UNICODE_STRING** y el valor de 0x0012FFBC a $t 15.

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

Los pseudo-registros definidos por el usuario usan cero como valor predeterminado cuando se inicia el depurador.

Nota Los alias $u 0, $u 1, ..., $u 9 no son pseudo-registros, a pesar de su apariencia similar. Para obtener más información sobre estos alias, consulte Uso de alias.

Ejemplo

En el ejemplo siguiente se establece un punto de interrupción que se alcanza cada vez que el subproceso actual llama a NtOpenFile. Pero este punto de interrupción no se alcanza cuando otros subprocesos llaman a NtOpenFile.

kd> bp /t @$thread nt!ntopenfile

Ejemplo

En el ejemplo siguiente se ejecuta un comando hasta que el registro contiene un valor especificado. En primer lugar, coloque el código siguiente para la ejecución paso a paso condicional en un archivo de script denominado "eaxstep".

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

A continuación, emita el siguiente comando.

t "$<eaxstep"

El depurador realiza un paso y, a continuación, ejecuta el comando . En este caso, el depurador ejecuta el script, que muestra 1234 o repite el proceso.