Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Отладчик поддерживает несколько псевдорегистров, которые содержат определенные значения.
Отладчик задает автоматические псевдорегистры для определенных полезных значений. Определяемые пользователем псевдорегистры — это целые переменные, в которые можно записывать или читать.
Все псевдорегистры начинаются с знака доллара ($). Если вы используете синтаксис MASM, вы можете добавить знак по знаку ( @ ) перед знаком доллара. Этот символ сообщает отладчику, что следующий токен является регистром или псевдорегистром, а не символом. Если вы опустите значок @, отладчик будет реагировать медленнее, так как ему приходится выполнять поиск по всей таблице символов.
Например, следующие две команды создают одинаковые выходные данные, но вторая команда быстрее.
0:000> ? $exp
Evaluate expression: 143 = 0000008f
0:000> ? @$exp
Evaluate expression: 143 = 0000008f
Если символ существует с тем же именем, что и псевдорегистр, необходимо добавить знак @.
Если используется синтаксис выражения C++, всегда требуется знак ( @ ).
Команда r (Registers) является исключением из этого правила. Отладчик всегда интерпретирует свой первый аргумент как регистр или псевдорегистратор. (Символ "@" не требуется и не разрешён.) Если для команды r есть второй аргумент, он интерпретируется в соответствии с синтаксисом выражения по умолчанию. Если синтаксис выражения по умолчанию — C++, необходимо использовать следующую команду, чтобы скопировать псевдорегистр $t2 в псевдорегистр $t1.
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* (отображаемая память). |
$proc |
Адрес текущего процесса (то есть адрес блока EPROCESS). |
$thread |
Адрес текущего потока. В отладке в режиме ядра этот адрес является адресом блока ETHREAD. В отладке в пользовательском режиме этот адрес — это адрес блока среды потока (TEB). |
$peb |
Адрес блока среды процесса (PEB) текущего процесса. |
$teb |
Адрес блока среды потока (TEB) текущего потока. |
$tpid |
Идентификатор процесса (PID) для процесса, которому принадлежит текущий поток. |
$tid |
Идентификатор потока для текущего потока. |
$dtid |
|
$dpid |
|
$dsid |
|
номер $bp |
Адрес соответствующей точки останова. Например, $bp 3 (или $bp 03) ссылается на точку останова, идентификатор точки останова которой равен 3. Число всегда является десятичным числом. Если ни одна точка останова не имеет ID равного Number, $bpNumber оценивается как ноль. Дополнительные сведения об точках останова см. в разделе "Использование точек останова". |
$frame |
Текущий индекс кадров. Этот индекс совпадает с номером кадра, который использует команда .frame (Set Local Context). |
$dbgtime |
Текущее время, в соответствии с компьютером, на котором работает отладчик. |
$callret |
Возвращаемое значение последней функции, которая вызывается (функция вызова) или используется в команде 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 при отладке мини-dump в пользовательском режиме или определенных файлов дампа в режиме ядра. В таких ситуациях вы можете узнать сведения о потоке из ~ (состояние потока), но не из $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 на всех процессорах.
Команду r можно использовать для изменения значения $ip. Это изменение также автоматически изменяет соответствующий регистр. При возобновлении выполнения, выполнение продолжается по новому адресу указателя инструкции. Этот регистр является единственным автоматическим псевдорегистром, который можно изменить вручную.
Заметка В синтаксисе MASM вы можете указать псевдорегистр $ip через точку (.). Вы не добавляете знак по адресу (@) до этого периода и не используете период в качестве первого параметра команды r . Этот синтаксис не допускается в выражении C++.
Автоматические псевдорегистры похожи на автоматические псевдонимы. Но вы можете использовать автоматические псевдонимы вместе с маркерами, связанными с псевдонимом (например, ${ }), и вы не можете использовать псевдорегистры с такими токенами.
User-Defined 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 или повторяет процесс.