Rediger

Del via


wt (Trace and Watch Data)

The wt command runs through the whole function and then displays statistics, when you execute this command at the beginning of a function call.

wt [WatchOptions] [= StartAddress] [EndAddress] 

Parameters

WatchOptions
Specifies how to modify the display. You can use any of the following options.

Option Effect

-l Depth

(User mode only) Specifies the maximum depth of the calls to display. Any calls that are at least Depth levels deeper than the starting point are executed silently.

-m Module

(User mode only) Restricts the display to code inside the specified module, plus the first level of calls made from that module. You can include multiple -m options to display code from multiple modules and no other modules.

-i Module

(User mode only) Ignores any code within the specified module. You can include multiple -i options to ignore code from multiple modules. If you use a -m option, the debugger ignores all -i options.

-ni

(User mode only) Does not display any entry into code that is being ignored because of an -m or -i option.

-nc

Does not display individual call information.

-ns

Does not display summary information.

-nw

Does not display warnings during the trace.

-oa

(User mode only) Displays the actual address of call sites.

-or

(User mode only) Displays the return register values of the called function, using the default radix as the base.

-oR

(User mode only) Displays the return register values of the called function, in the appropriate type for each return value.

StartAddress
Specifies the address where the debugger begins execution. If you do not use StartAddress, execution begins at the instruction that the instruction pointer points to. For more information about the syntax, see Address and Address Range Syntax.

EndAddress
Specifies the address where tracing ends. If you do not use EndAddress, a single instruction or function call is executed.

Environment

Modes

User mode, kernel mode

Targets

Live debugging only

Platforms

User mode: all Kernel mode: x86-based only

Additional Information

For more information about issuing the wt command and an overview of related commands, see Controlling the Target.

Remarks

The wt command is useful if you want information about the behavior of a specific function, but you do not want to step through the function. Instead, go to the beginning of that function and then issue the wt command.

If the program counter is at a point that corresponds to a symbol (such as the beginning of a function or entry point into a module), the wt command traces until it reaches the current return address. If the program counter is on a call instruction, the wt command traces until it returns to the current location. This tracing is profiled in the Debugger Command window together with output that describes the various calls that the command encounters.

If the wt command is issued somewhere other than the beginning of a function, the command behaves like the p (Step) command. However, if you specify EndAddress, execution continues until that address is reached, even if this execution involves many program steps and function calls.

When you are debugging in source mode, you should trace into the function only to the point where you see the opening bracket of the function body. Then, you can use the wt command. (It is typically easier to insert a breakpoint at the first line of the function, or use Debug | Run to Cursor, and then use the wt command.)

Because the output from wt can be long, you might want to use a log file to record your output.

The following example shows a typical log file.

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

In the listing of the trace, the first number specifies the number of instructions that were executed, the second number specifies the number of instructions executed by child processes of the function, and the third number (in brackets) specifies the depth of the function in the stack (taking the initial function as zero). The indentation of the function name shows the call depth.

In the preceding example, MyModule!myFunction executes 105 instructions before it calls several subroutines, including printf and fgets, and then executes 54545 additional instructions after calling those functions, but before issuing a few more calls. However, in the final count, the display shows that myFunction executes 112,379 instructions, because this count includes all of the instructions that myFunction and its children execute. (The children of myFunction are functions that are called from myFunction, either directly or indirectly.)

In the preceding example, note also that ILT+1440 (__isatty) is called 21 times. In the final count, the summary of this function's behavior shows the number of times that it was called, the smallest number of instructions in any single execution, the largest number of instructions in any single execution, and the average number of instructions per execution.

If any system calls are made, they appear in the counter and are listed again at the end of the command output.