Skip to main content

Watchpoints

Overview of the watch command.

About

A watchpoint is a data breakpoint. This means the program stops when the variable (or expression, or raw memory region) being observed by the watchpoint is changed. Currently, watchpoints are based on x86-64 hardware breakpoints, which introduces two limitations:

  • Only 4 watchpoints can be active at once.
  • Watchpoints can only observe memory regions of 1, 2, 4, or 8 bytes in size.

Setting watchpoints

You can set a watchpoint on variables (global or local) or on expressions involving variables. Watchpoints for local variables are automatically removed when the variable goes out of scope. If a watchpoint observes a global variable, it remains active as long as the debugger is running.

Watchpoints are set with the watch (or just w) command:

  • watch [+rw][+w] ( <addr>:<size> | <DQE> ) - set write or read-write watchpoint (write by default) for a memory location (size must be one of [1,2,4,8] bytes) or DQE with variable
  • watch remove ( <addr>:<size> | <expression> | <number> ) - deactivate and delete the selected watchpoint
  • watch info - show all watchpoints

Some examples of setting watchpoints:

  • watch my_var (alias: w my_var) - stop when variable value is rewritten
  • watch +rw my_var - stop when variable value is read or rewritten
  • watch my_vector[0] - stop when the first vector element is rewritten
  • watch (~my_vector).len - stop when vector length changes
  • watch 0x100:4 - stop when writing to memory region [0x100:0x103]

Usage example

Consider this Rust function:

fn calculate_and_print(mut val: i32) {
val += 1;
val += 2;
val -= 5;

print!("{val}");
}

Let's watch the val argument: