Conditional Watchpoints
If you associate an expression with a watchpoint (by selecting the CDWP icon in the Tools > Watchpoint dialog box and entering an expression), TotalView will evaluate the expression after the watchpoint triggers. The programming statements that you can use in this area are identical to those that you can use when creating an evaluation point, except that you cannot call functions from a watchpoint expression.
The variables used in watchpoint expressions must be global. This is because the watchpoint can be triggered from any procedure or scope within your program.
Because memory locations are not scoped, the variable used in your expression must be globally accessible.
Note: Fortran does not have global variables. Consequently, you cannot directly refer to your program's variables.
TotalView has two intrinsic variables that are specifically designed to be used with conditional watchpoint expressions:
$oldval
The value of the memory locations before a change is made.
$newval
The value of the memory locations after a change is made.
Here is an expression that uses these values:
if (iValue != 42 && iValue != 44) {
iNewValue = $newval; iOldValue = $oldval; $stop;}
When the value iValue global variable is neither 42 nor 44, TotalView will store the new and old memory values in the iNewValue and iOldValue variables. These variables are defined in the program. (Storing the old and new values is a convenient way of letting you monitor the changes made by your program.)
Here is a condition that triggers a watchpoint when a memory location's value becomes negative:
if ($oldval >= 0 && $newval < 0) $stop
And here's a condition that triggers a watchpoint when the sign of the value in the memory location changes:
if ($newval * $oldval <= 0) $stop
Both of these examples require that you set the Type for $oldval/$newval field in the Watchpoint Properties dialog box.
For more information on writing expressions, see Writing Code Fragments.
If a watchpoint has the same length as the $oldval or $newval data type, the value of these variables is apparent. However, if the data type is shorter than the length of the watch region, TotalView searches for the first changed location in the watched region and uses that location for $oldval and $newval variables. (It aligns data within the watched region based on the size of the data's type. For example, if the data type is a 4-byte integer and byte 7 in the watched region changes, TotalView uses bytes 4 through 7 of the watchpoint when it assigns values to these variables.)
For example, suppose you are watching an array of 1000 integers called must_be_positive and you want to trigger a watchpoint as soon as one element becomes negative. You would declare the type for $oldval and $newval to be int and use the following condition:
if ($newval < 0) $stop;
When your program writes a new value to the array, TotalView triggers the watchpoint, sets the values of $oldval and $newval, and evaluates the expression. When $newval is negative, the $stop statement halts the process.
This can be a very powerful technique for range checking all the values written into an array. (Because of byte length restrictions, you can only use this technique on IRIX and Solaris.)
Note: Conditional watchpoints are always interpreted by TotalView; they are never compiled. And, because interpreted watchpoints are single threaded within TotalView, every process or thread that writes to the watched location must wait for other instances of the watchpoint to finish executing. This can adversely affect performance.