If you associate an expression with a watchpoint (by selecting the Conditional button in theWatchpoint Properties dialog boxentering an expression), TotalView evaluates the expression after the watchpoint triggers. The programming statements that you can use are identical to those used when you create an eval point, except that you can’t 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 in your program.
NOTE >> Fortran does not have global variables. Consequently, you can’t directly refer to your program’s variables.
TotalView has two variables that are used exclusively 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.
The following is an expression that uses these values:
if (iValue != 42 && iValue != 44) {
iNewValue = $newval; iOldValue = $oldval; $stop;}
When the value of the iValue global variable is neither 42 nor 44, TotalView stores 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.)
The following condition triggers a watchpoint when a memory location’s value becomes negative:
if ($oldval >= 0 && $newval < 0) $stop
And, here is 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.
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 the $oldval and $newval variables. (It aligns data in 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’re 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 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 your program writes into an array. (Because of byte length restrictions, you can only use this technique on Solaris.)
NOTE >> On all platforms except for IBM AIX, TotalView always interprets conditional watchpoints; it never compiles them. Because interpreted watchpoints are single-threaded in 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.