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:
(idb) whatis _nextNode
class 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 C::foo(void)
[#3: stop variable t write within void C::foo(void)]
(idb) cont
Select from
----------------------------------------------------
1 int C::foo(double*)
2 void C::foo(float)
3 void C::foo(int)
4 void C::foo(void)
5 None of the above
----------------------------------------------------
5
Value of <overloaded function> not completely specified
foo is not a valid breakpoint address
[3] Address 0x0804d5d0 was accessed at:
void C::foo(void): src/x_overload.cxx
[line 22, 0x08048789] foo+0x3: movl $0x0, 0x804d5d0
0x0804d5d0: Old value = 0x0000000f
0x0804d5d0: New value = 0x00000000
[3] stopped at [void C::foo(void):22 0x08048793]
22 void C::foo() { t = 0; state++; return; }