Синтаксис 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 , либо повторяет процесс.