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


wt (данные трассировки и просмотра)

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

wt [WatchOptions] [= StartAddress] [EndAddress] 

Параметры

WatchOptions
Указывает, как изменить отображение. Вы можете использовать любой из следующих параметров.

Вариант Действие

-l Глубина

(Только в пользовательском режиме) Задает максимальную глубину отображаемых вызовов. Все вызовы, которые имеют по крайней мере уровни глубины , более глубокие, чем начальная точка, выполняются автоматически.

Модуль -m

(Только в пользовательском режиме) Ограничивает отображение кода внутри указанного модуля, а также первый уровень вызовов, выполненных из этого модуля. Можно включить несколько параметров -m для отображения кода из нескольких модулей и других модулей.

-i Module

(Только в пользовательском режиме) Игнорирует любой код в указанном модуле. Можно включить несколько параметров -i, чтобы игнорировать код из нескольких модулей. При использовании параметра -m отладчик игнорирует все параметры -i.

-ni

(Только в пользовательском режиме) Не отображает никакой записи в код, который игнорируется из-за параметра -m или -i.

-nc

Не отображается отдельная информация о вызове.

-ns

Не отображает сводную информацию.

-nw

Не отображает предупреждения во время трассировки.

-Оа

(Только в пользовательском режиме) Отображает фактический адрес сайтов звонков.

-or

(Только в пользовательском режиме) Отображает возвращаемые значения регистра вызываемой функции, используя радикс по умолчанию в качестве основы.

-или

(Только в пользовательском режиме) Отображает возвращаемые значения регистра вызываемой функции в соответствующем типе для каждого возвращаемого значения.

StartAddress
Указывает адрес, в котором начинается выполнение отладчика. Если вы не используете StartAddress, выполнение начинается с инструкции, на которую указывает указатель инструкции. Дополнительные сведения о синтаксисе см. в разделе "Синтаксис адреса и диапазон адресов".

EndAddress
Указывает адрес, в котором заканчивается трассировка. Если вы не используете EndAddress, выполняется одна инструкция или вызов функции.

Среда

Режимы

Режим пользователя, режим ядра

Целевые объекты

Только динамическая отладка

Платформы

Пользовательский режим: весь режим ядра: только на основе x86

Дополнительная информация

Дополнительные сведения о выпуске команды wt и обзоре связанных команд см. в разделе "Управление целевым объектом".

Замечания

Команда wt полезна, если требуется информация о поведении определенной функции, но вы не хотите выполнить шаг через функцию. Вместо этого перейдите к началу этой функции, а затем выполните команду wt .

Если счетчик программы находится в точке, которая соответствует символу (например, началу функции или точки входа в модуль), команда wt трассирует до тех пор, пока не достигнет текущего возвращаемого адреса. Если счетчик программы находится в инструкции вызова, команда wt трассирует до тех пор, пока она не вернется в текущее расположение. Эта трассировка профилируется в командном окне отладчика вместе с выходными данными, описывающими различные вызовы, с которыми сталкивается команда.

Если команда wt выдана где-то, отличном от начала функции, команда ведет себя как команда p (шаг). Однако если указать EndAddress, выполнение продолжается до тех пор, пока этот адрес не будет достигнут, даже если это выполнение включает в себя множество шагов программы и вызовов функций.

При отладке в исходном режиме следует отследить функцию только до точки, в которой отображается открывающая скобка тела функции. Затем можно использовать команду wt . (Обычно проще вставлять точку останова в первой строке функции или использовать Отладка | Запустите на курсор, а затем используйте команду wt .)

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

В следующем примере показан типичный файл журнала.

0:000> l+                  Source options set to show source lines
Source options are f:
     1/t - Step/trace by source line
     2/l - List source line for LN and prompt
     4/s - List source code at prompt
     8/o - Only show source code at prompt
0:000> p                   Not yet at the function call: use "p"
>  44:       minorVariableOne = 12;
0:000> p
>  45:       variableOne = myFunction(2, minorVariable);
0:000> t                   At the function call: now use "t"
MyModule!ILT+10(_myFunction):
0040100f e9cce60000      jmp     MyModule!myFunction (0040f6e0)
0:000> t
>  231:    { 
0:000> wt                  At the function beginning:  now use "wt"
Tracing MyModule!myFunction to return address 00401137

  105     0 [  0] MyModule!myFunction
    1     0 [  1]   MyModule!ILT+1555(_printf)
    9     0 [  1]   MyModule!printf
    1     0 [  2]     MyModule!ILT+370(__stbuf)
   11     0 [  2]     MyModule!_stbuf
    1     0 [  3]       MyModule!ILT+1440(__isatty)
   14     0 [  3]       MyModule!_isatty
   50    15 [  2]     MyModule!_stbuf
   17    66 [  1]   MyModule!printf
    1     0 [  2]     MyModule!ILT+980(__output)
   59     0 [  2]     MyModule!_output
   39     0 [  3]       MyModule!write_char
  111    39 [  2]     MyModule!_output
   39     0 [  3]       MyModule!write_char

....

   11     0 [  5]           kernel32!__SEH_epilog4
   54 11675 [  4]         kernel32!ReadFile
  165 11729 [  3]       MyModule!_read
  100 11895 [  2]     MyModule!_filbuf
   91 11996 [  1]   MyModule!fgets
54545 83789 [  0] MyModule!myFunction
    1     0 [  1]   MyModule!ILT+1265(__RTC_CheckEsp)
    2     0 [  1]   MyModule!_RTC_CheckEsp
54547 83782 [  0] MyModule!myFunction

112379 instructions were executed in 112378 events (0 from other threads)

Function Name                               Invocations MinInst MaxInst AvgInst
MyModule!ILT+1265(__RTC_CheckEsp)                     1       1       1       1
MyModule!ILT+1440(__isatty)                          21       1       1       1
MyModule!ILT+1540(__ftbuf)                           21       1       1       1
....
ntdll!memcpy                                         24       1      40      19
ntdll!memset                                          2      29      29      29

23 system calls were executed

Calls  System Call
   23  ntdll!KiFastSystemCall

В списке трассировки первый номер указывает количество выполненных инструкций, второе число определяет количество инструкций, выполняемых дочерними процессами функции, а третий номер (в скобках) указывает глубину функции в стеке (принимая начальную функцию как ноль). Отступ имени функции показывает глубину вызова.

В предыдущем примере MyModule!myFunction выполняет 105 инструкций перед вызовом нескольких вложенных элементов, включая printf и fgets, а затем выполняет дополнительные инструкции 54545 после вызова этих функций, но перед выполнением нескольких вызовов. Однако в последнем счетчике отображается, что myFunction выполняет 112 379 инструкций, так как это число включает все инструкции, которые выполняют myFunction и его дочерние элементы. (Дочерние элементы myFunction — это функции, которые вызываются из myFunction напрямую или косвенно.)

В предыдущем примере обратите внимание, что ILT+1440 (__isatty) вызывается 21 раз. В окончательном подсчете сводка поведения этой функции показывает количество вызовов, наименьшее количество инструкций в любом отдельном выполнении, наибольшее количество инструкций в любом отдельном выполнении и среднее число инструкций на выполнение.

Если выполняются какие-либо системные вызовы, они отображаются в счетчике и снова отображаются в конце выходных данных команды.