You can monitor a region of memory for specific kinds of memory accesses by setting a Purify watchpoint on it. Using watchpoints simplifies the task of debugging problems where memory mysteriously changes between the time it is initialized and the time it is used.
Purify watchpoints can report:
Reads (WPR)
Writes (WPW)
Allocations (WPM)
Deallocations (WPF)
Coming into scope at function entry (WPN)
Going out of scope at function exit (WPX)
When you set a watchpoint, Purify automatically reports the exact cause and result of each memory access, even when you are not using a debugger. Since Purify already intercepts every memory access as part of its dynamic error detection, you can use watchpoints without any performance degradation.
Watchpoints are useful when:
Memory is being improperly deallocated. Set a watchpoint on the memory to have Purify report when the memory is allocated and deallocated, and who is doing the allocating and deallocating.
System calls fail intermittently. Set a watchpoint on the global system variable errno to have Purify report a diagnostic message whenever errno is written.
A counter is not incrementing properly. Set a watchpoint on the counter and wait for the improper change.
Global data is being overwritten improperly. Set a watchpoint on the global memory and wait for writes to that region.
A segment of read-only data is being changed. Set a watchpoint on the memory segment that should not change during execution. The memory segment does not need to begin on page boundaries, and there is no limit on the size of the memory segment that Purify can watch.
Watchpoints in many debuggers are sometimes implemented by single-stepping the program, and checking whether the value of a watched variable changes after each instruction. Under gdb, watching a single 4-byte word can slow the program by a factor of 1,000 or more.
Purify implements watchpoints by monitoring the addresses of the loads and stores performed by the program. This makes using Purify's watchpoints fast; there is no performance loss for requesting watchpoints, even those covering large regions of memory.
Purify's watchpoints are also more sensitive than those of a debugger. Purify warns you when watched data is read, when watched data in the heap is allocated or deallocated, and when watched data on the stack comes into or goes out of scope as it is included in the local variables of a function. Purify also catches a write to a watched variable when the value being written is unchanged.
You can set a watchpoint and then enable Purify's Just-In-Time debugging feature to start your debugger when Purify encounters the watchpoint.
Notes:
You can watch memory in the stack, heap, bss, data, text, and mmap'd segments of your program.
You can monitor variables or memory addresses within the scope of a function call (local variables). Purify's watchpoints indicate when the variable comes into or goes out of scope.
Watchpoints work for system calls, but they do not work for kernel trap handlers. If you set a watchpoint on the stack, a trap handler running in kernel mode can set that stack memory without triggering a Purify watchpoint. Code that processes an interrupt signal does trigger watchpoints—although the kernel trap handler does not.
Unlike the .purify file, Purify reads the ./<programname>.watchpoints file only when the program starts up.
In optimized code, the compiler can store a value in a register for later use instead of generating a read each time your program uses that variable. In these cases, Purify's read watchpoints are triggered only on the original access of the variable and not by subsequent reuses of the register value.