Поделиться через


Синтаксис Pseudo-Register

Отладчик поддерживает несколько псевдорегистров, которые содержат определенные значения.

Отладчик устанавливает для автоматических псевдорегистров определенные полезные значения. Определяемые пользователем псевдорегистры — это целочисленные переменные, которые можно записывать или считывать.

Все псевдорегистры начинаются со знака доллара ($). Если вы используете синтаксис MASM, вы можете добавить знак @ () перед знаком доллара. Этот знак at сообщает отладчику, что следующий маркер является регистром или псевдорегистрателем, а не символом. Если опустить знак at, отладчик отвечает медленнее, так как ему приходится искать всю таблицу символов.

Например, следующие две команды создают одинаковые выходные данные, но вторая команда выполняется быстрее.

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

Если существует символ с тем же именем, что и псевдорегистра, необходимо добавить знак at.

При использовании синтаксиса выражений C++ всегда требуется знак at ( @ ).

Команда r (Registers) является исключением из этого правила. Отладчик всегда интерпретирует свой первый аргумент как регистр или псевдорегистрал. (Знак при не требуется или не разрешен.) Если для команды r есть второй аргумент, он интерпретируется в соответствии с синтаксисом выражения по умолчанию. Если синтаксис выражений по умолчанию — C++, необходимо скопировать псевдорегистрал $t 2 в псевдорегистратив $t 1 .

0:000> r $t1 = @$t2

Автоматическое Pseudo-Registers

Отладчик автоматически задает следующие псевдорегистры.

Псевдорегистрал Описание

$ea

Действующий адрес последней выполненной инструкции. Если у этой инструкции нет эффективного адреса, отладчик отображает сообщение "Ошибка неправильной регистрации". Если эта инструкция имеет два эффективных адреса, отладчик отображает первый адрес.

$ea 2

Второй действующий адрес последней выполненной инструкции. Если у этой инструкции нет двух эффективных адресов, отладчик отображает сообщение "Ошибка неправильной регистрации".

$exp

Последнее вычисляемого выражения.

$ra

Обратный адрес, который в данный момент находится в стеке.

Этот адрес особенно полезен при выполнении команд. Например, g @$ra продолжается до тех пор, пока не будет найден обратный адрес (хотя gu (Go Up) является более точным эффективным способом "выхода" из текущей функции).

$ip

Регистр указателя инструкций.

Процессоры на базе x86: То же, что и eip. Процессоры на основе Itanium: Связанные с iip. (Дополнительные сведения см. в примечании к этой таблице.) Процессоры на базе x64: То же, что и rip.

$eventip

Указатель инструкции во время текущего события. Этот указатель обычно соответствует $ip, если вы не переключили потоки или вручную не изменили значение указателя инструкции.

$previp

Указатель инструкции во время предыдущего события. (Разрыв в отладчике считается событием.)

$relip

Указатель инструкции, связанный с текущим событием. При трассировке ветвей этот указатель является указателем на источник ветви.

$scopeip

Указатель инструкций для текущего локального контекста (также известного как область).

$exentry

Адрес точки входа первого исполняемого файла текущего процесса.

$retreg

Основной регистр возвращаемого значения.

Процессоры на базе x86: То же, что и eax. Процессоры на основе Itanium: То же, что и ret0. Процессоры на базе x64: То же, что и rax.

$retreg 64

Регистр основного возвращаемого значения в 64-разрядном формате.

Процессор x86: То же, что и пара edx:eax .

$csp

Текущий указатель на стек вызовов. Этот указатель является регистром, который является наиболее репрезентативным для глубины стека вызовов.

Процессоры на базе x86: То же, что и esp. Процессоры на основе Itanium: То же, что и bsp. Процессоры на базе x64: То же, что и rsp.

$p

Значение, напечатанное последней командой d* (display Memory).

$proc

Адрес текущего процесса (то есть адрес блока EPROCESS).

$thread

Адрес текущего потока. При отладке в режиме ядра этот адрес является адресом блока ETHREAD. При отладке в пользовательском режиме этот адрес является адресом блока среды потока (TEB).

$peb

Адрес блока среды процесса (PEB) текущего процесса.

$teb

Адрес блока среды потока (TEB) текущего потока.

$tpid

Идентификатор процесса (PID) для процесса, которому принадлежит текущий поток.

$tid

Идентификатор потока для текущего потока.

$dtid

$dpid

$dsid

Число $bp

Адрес соответствующей точки останова. Например, $bp 3 (или $bp 03) относится к точке останова, идентификатор которой равен 3. Число всегда является десятичным числом. Если ни один из точек останова не имеет идентификатора Number, число $bpпринимает значение 0. Дополнительные сведения о точках останова см. в разделе Использование точек останова.

$frame

Индекс текущего кадра. Этот индекс является тем же номером кадра, который используется командой .frame (Set Local Context).

$dbgtime

Текущее время в соответствии с компьютером, на котором запущен отладчик.

$callret

Возвращаемое значение последней функции, вызываемой функцией .call (Call Function) или используемой в команде .fnret /s . Тип данных $callret является типом данных этого возвращаемого значения.

$extret

$extin

$clrex

$lastclrex

Только управляемая отладка: Адрес последнего обнаруженного объекта исключения среды CLR.

$ptrsize

Размер указателя. В режиме ядра этот размер является размером указателя на целевом компьютере.

$pagesize

Количество байтов на одной странице памяти. В режиме ядра это размер страницы на целевом компьютере.

$pcr

$pcrb

$argreg

$exr_шанс

Вероятность текущей записи исключения.

$exr_code

Код исключения для текущей записи исключения.

$exr_numparams

Количество параметров в текущей записи исключения.

$exr_param0

Значение параметра 0 в текущей записи исключения.

$exr_param1

Значение параметра 1 в текущей записи исключения.

$exr_param2

Значение параметра 2 в текущей записи исключения.

$exr_param3

Значение параметра 3 в текущей записи исключения.

$exr_param4

Значение параметра 4 в текущей записи исключения.

$exr_param5

Значение параметра 5 в текущей записи исключения.

$exr_param6

Значение параметра 6 в текущей записи исключения.

$exr_param7

Значение параметра 7 в текущей записи исключения.

$exr_param8

Значение параметра 8 в текущей записи исключения.

$exr_param9

Значение параметра 9 в текущей записи исключения.

$exr_param10

Значение параметра 10 в текущей записи исключения.

$exr_param11

Значение параметра 11 в текущей записи исключения.

$exr_param12

Значение параметра 12 в текущей записи исключения.

$exr_param13

Значение параметра 13 в текущей записи исключения.

$exr_param14

Значение параметра 14 в текущей записи исключения.

$bug_code

Если произошла ошибка проверка, это код ошибки. Применяется к динамической отладке в режиме ядра и аварийным дампам ядра.

$bug_param1

Если произошла ошибка проверка, это значение параметра 1. Применяется к динамической отладке в режиме ядра и аварийным дампам ядра.

$bug_param2

Если произошла ошибка проверка, это значение параметра 2. Применяется к динамической отладке в режиме ядра и аварийным дампам ядра.

$bug_param3

Если произошла ошибка проверка, это значение параметра 3. Применяется к динамической отладке в режиме ядра и аварийным дампам ядра.

$bug_param4

Если произошла ошибка проверка, это значение параметра 4. Применяется к динамической отладке в режиме ядра и аварийным дампам ядра.

Некоторые из этих псевдорегистров могут быть недоступны в некоторых сценариях отладки. Например, нельзя использовать $peb, $tid и $tpid при отладке минидампов в пользовательском режиме или определенных файлов дампа в режиме ядра. В некоторых ситуациях сведения о потоке можно получить из ~ (состояние потока), но не из $tid. Вы не можете использовать $previp псевдорегистрару в первом событии отладчика. Вы не можете использовать $relip псевдорегистративную регистрацию, если не выполняется трассировка ветви. Если вы используете недоступный псевдорегистр, возникает синтаксическая ошибка.

Псевдорегистратор, содержащий адрес структуры, такой как $thread, $proc, $teb, $peb и $lastclrex , будет вычисляться в соответствии с соответствующим типом данных в средстве оценки выражений C++, но не в вычислителе выражений MASM. Например, команда ? $teb отображает адрес TEB, а команда ?? @$teb — всю структуру TEB. Дополнительные сведения см. в разделе Вычисление выражений.

На процессоре на основе Itanium регистр IIPвыравнивается по пакету, что означает, что он указывает на слот 0 в пакете, содержающем текущую инструкцию, даже если выполняется другой слот. Таким образом , iIP не является полным указателем инструкции. Псевдорегистративная $ip — это фактический указатель инструкции, включая пакет и слот. Другие псевдорегистры, в которых содержатся указатели адресов ($ra, $retreg, $eventip, $previp, $relip и $exentry), имеют ту же структуру, что и $ip на всех процессорах.

Для изменения значения $ip можно использовать команду r. Это изменение также автоматически изменяет соответствующий регистр. При возобновлении выполнения оно возобновляется по новому адресу указателя инструкции. Это единственный автоматический псевдорегистрат, который можно изменить вручную.

Примечание В синтаксисе MASM можно указать $ip псевдорегистрару с точкой ( . ). Вы не добавляете знак at (@) до этого периода и не используете точку в качестве первого параметра команды r . Этот синтаксис не допускается в выражении C++.

Автоматические псевдорегистры похожи на автоматические псевдонимы. Но вы можете использовать автоматические псевдонимы вместе с маркерами, связанными с псевдонимами (например , ${ }), и с такими маркерами нельзя использовать псевдорегистры.

Определяемые пользователем Pseudo-Registers

Существует 20 определяемых пользователем псевдорегистров ($t 0, $t 1, ..., $t 19). Эти псевдорегистрали являются переменными, которые можно считывать и записывать с помощью отладчика. В этих псевдорегистрах можно хранить любое целочисленное значение. Они могут быть особенно полезны в качестве переменных цикла.

Чтобы записать данные в один из этих псевдорегистров, используйте команду r (Registers), как показано в следующем примере.

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

Как и все псевдорегистры, можно использовать определяемый пользователем псевдорегистрал в любом выражении, как показано в следующем примере.

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

Псевдорегистрал всегда вводится как целое число, если только вы не используете параметр ? вместе с командой r . Если вы используете этот параметр, псевдорегистрал получает тип того, что ему назначено. Например, следующая команда назначает тип UNICODE_STRING** и значение 0x0012FFBC $t 15.

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

Определяемые пользователем псевдорегистраторы используют ноль в качестве значения по умолчанию при запуске отладчика.

Примечание Псевдонимы $u 0, $u 1, ..., $u 9 не являются псевдорегистралами, несмотря на их похожий внешний вид. Дополнительные сведения об этих псевдонимах см. в разделе Использование псевдонимов.

Пример

В следующем примере задается точка останова, которая достигается каждый раз, когда текущий поток вызывает NtOpenFile. Но эта точка останова не достигается, когда другие потоки вызывают NtOpenFile.

kd> bp /t @$thread nt!ntopenfile

Пример

В следующем примере команда выполняется до тех пор, пока регистр не содержит указанное значение. Сначала поместите следующий код для условного пошагового выполнения в файл скрипта с именем eaxstep.

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

Затем выполните следующую команду.

t "$<eaxstep"

Отладчик выполняет шаг, а затем выполняет команду . В этом случае отладчик запускает скрипт, который либо отображает 1234 , либо повторяет процесс.