WET Home

WET Trace Format

WET produces tracing information from a program execution in one of two possible formats. The first format provides comprehensive tracing information. The second format provides dynamic dependences for a limited execution history.


Comprehensive Tracing Information

The dynamic comprehensive tracing information includes the statements exercised, the dependences exercised, and the values computed at each exercised statement instance. The general format of this tracing output is as follows.

N
instruction_block 1
instruction_block 2
...
instruction_block N

The first line (N) denotes the total number of dynamically-executed instructions for which tracing information is collected. This number represents the total number of instruction_block entries. Each instruction_block entry contains all the tracing information for a particular executed instruction. The general format of each instruction_block is as follows.

static_info
dependences
values_computed

The first entry (static_info), is a single line containing 6 distinct kinds of static information.

id num_use_port instr_addr file_name function_name line_num

The first field (id) is a unique numerical identifier for the instruction. The second field (num_use_port) is the number of static uses (dependences) for the instruction. For example, the instruction mov (%ebp),%eax that moves from a memory location into a register has three possible uses: register %ebp; the memory location addressed by register %ebp; and the control dependence, which is considered as a separate use. The third field (instr_addr) denotes the instruction address of the current instruction. The remaining fields (file_name, function_name, and line_num) respectively denote the file name, the function name, and the source code line number of the current instruction. Note that these last three values are available only if the executable has debugging information available.

The second entry of each instruction_block (dependences), shows the dynamic dependence information for each use port of the current instruction (as specified by the num_use_port value). The information for each use port is presented in the following format. Note that the first use port always denotes control dependence, and the other use ports refer to data dependences.

SIZE N
    0:dep_id instance
    1:dep_id instance
    ...
    N-1:dep_id instance

The first line (SIZE N) denotes the number of dynamic instruction instances in which the current use port has a dependence (it may happen that an instruction may not have any control dependences, in which case the value for N may be 0). The dependence information for each instance of the current use port is then presented in the subsequent lines. An entry X:Y Z indicates that the Xth instance of the given use port for the instruction is dependent upon the Zth instance of the instruction with unique id Y.

The third entry of each instruction_block (values_computed), shows the actual values defined by the current instruction at each execution instance. In the event that the instruction does not define any values, this will be indicated by the following line.

NO VALUES

On the other hand, if values are defined at the given instruction, they are indicated as follows.

VALUES N
    0:hex_value
    1:hex_value
    ...
    N-1:hex_value

Here, N denotes the number of instances in which the current instruction defined a value. The defined value information for each instance is then presented in the following lines. An entry X:Y indicates that the Xth instance of the current instruction computed value Y. Note that Y is expressed in hexadecimal format.


Dynamic Dependences for a Limited Execution History

This tracing format is targeted toward a debugging scenario. In this format, dynamic tracing information is collected during runtime into a circular, fixed-sized buffer. The size of the buffer is set by default to 100,000 dependences, though this will be made to be user-configurable in the next release. Since these dependences are maintained in a circular buffer, some dependences will be overwritten if the buffer gets full. Thus, these dependences represent a limited execution history. In this format, each line of data represents a single dependence recorded in the dependence buffer, and has the following general format.

a#b --> x#y

In this entry, the arrow --> is read as "depends upon". The above entry indicates that the bth instance of the instruction with address a, is dependent upon the yth instance of the instruction with address x.


Example

Let us consider a simple program called "foo1.c" (source code). The program is shown below.

1: int x, y, result;
2: int main(int argc, char **argv)
3: {
4:     if(argc >= 3)
5:     {
6:        x = atoi(argv[1]);
7:        y = atoi(argv[2]);
8:        result = x * 7;
9:        result = result + y;
10:       printf("result is %d\n", result);
11:    }
12: }

We will assume in this example that Diablo has been installed so that control dependence information is reflected in the computed tracing information.

Note that in the above example program, statement 8 is control dependent upon statement 4 and data dependent upon statement 6. Suppose the program "foo1.c" is compiled with debugging information, and that the program is executed with the command "foo1 2 7". Then the comprehensive tracing information is as shown here, and the dynamic dependences for a limited execution history are as shown here.

We first consider the comprehensive tracing information (seen here). The first instruction corresponding to statement 8 has the instruction address 0x8048242 with id 2118. The corresponding tracing data in the instruction_block is the following.

2118 2 8048242 foo1.c main 8
SIZE 1
    0:1873 0
SIZE 1
    0:2113 0
VALUES 1
    0:2

We can see from the first data line that this instruction occurs in file "foo1.c", function "main", and there are 2 use ports for this instruction. The first use port is for control dependence. We can see that the 0th instance of this instruction is control dependent upon the 0th instance of the instruction with id 1873. Upon looking up this other instruction_block, we see the following first line.

1873 2 8048210 foo1.c main 4

As expected, this indicates that the instruction at statement 8 is control dependent upon an instruction at statement 4. Next, the second use port of the instruction at statement 8 indicates that there is a data dependence upon the 0th instance of the instruction with id 2113. Upon looking up this other instruction_block, we see the following first line.

2113 2 8048225 foo1.c main 6

Thus, this indicates that the instruction at statement 8 is, as expected, data dependent upon an instruction at statement 6. Finally, the instruction_block for the instruction at statement 8 above shows that in the first executed instance, there was a value 0x2 defined by the statement. This is because when the program was executed, the inputted value for variable "x" was 2.

Now, let us consider the dynamic dependences for a limited execution history (seen here). The two dependences described above are represented in the tracing data by the following two lines.

0x8048242#0 --> 0x8048210#0
0x8048242#0 --> 0x8048225#0