You can use watch detectors to determine when a variable or other memory location is read or written and/or changed. Breakpoints with watch detectors are also known as watchpoints.
watch_detector
: basic_watch_detector watch_detector_modifiers
basic_watch_detector
| memory start_address_expression
| memory start_address_expression , end_address_expression
| memory start_address_expression : byte_count_expression
watch_detector_modifiers
: [ access_modifier ] [ within_modifier ]
access_modifier
: write
| read
| changed
| any
within_modifier
You can specify a variable whose memory is to be watched, or specify the memory directly. The accesses that are considered can be limited to those that write (the default), read, write and actually change the value, or can include all accesses.
If you specify a variable, the memory to be watched includes all of the memory for that variable, as determined by the variable's type. The following example watches for write access to variable _nextNode, which is allocated in the 8 bytes at the address shown in the last line of the example:
(idb) whatis _nextNode
struct Node* Node::_nextNode
(idb) print "sizeof(_nextNode) =", sizeof((_nextNode))
sizeof(_nextNode) = 4
(idb) stop variable _nextNode write
[#3: stop variable _nextNode write]
The specified variable is watched. If "p" is a pointer, watch variable p will watch the content of the pointer, not the memory pointed to by "p". Use watch memory *p to watch the memory pointed to by "p".
If you specify memory directly in terms of its address, the memory to be watched is defined as follows:
By default (no last address or size given), then 8 bytes beginning at the given start address:
(idb) when memory &_nextNode : 8 any
[#4: when memory &_nextNode : 8 any]
If an end address is given, then all bytes of memory from the start address to and including the end address:
(idb) stop memory &_nextNode, ((long)&_nextNode) + 3 read
[#5: stop memory &_nextNode, ((long)&_nextNode) + 3 read]
This watches the 4 bytes specified on the command line.
If you specify a byte count, then the given number of bytes starting at the given start address:
(idb) stop memory &_nextNode : 2 changed
[#6: stop memory &_nextNode : 2 changed]
This watches the 2 bytes specified on the command line for a change in contents.
If you specify the within modifier, then only those accesses that occur within the given function (but not any function it calls) are watched. For example:
(idb) whatis t
int t
(idb) stop variable t write within foo
[#2: stop variable t write within void C::foo(void)]
(idb) cont
[2] Address 0x0804d5c8 was accessed at:
void C::foo(void): src/x_overload.cxx
[line 22, 0x08048721] foo+0x3: movl $0x0, 0x804d5c8
0x0804d5c8: Old value = 0x0000000f
0x0804d5c8: New value = 0x00000000
[2] stopped at [void C::foo(void):22 0x0804872b]
22 void C::foo() { t = 0; state++; return; }