GDB Internals
3.8 Watchpoints
Watchpoints are a special kind of breakpoints (see section breakpoints) which break when data is accessed rather than when some
instruction is executed. When you have data which changes without
your knowing what code does that, watchpoints are the silver bullet to
hunt down and kill such bugs.
Watchpoints can be either hardware-assisted or not; the latter type is
known as "software watchpoints." GDB always uses
hardware-assisted watchpoints if they are available, and falls back on
software watchpoints otherwise. Typical situations where GDB
will use software watchpoints are:
-
The watched memory region is too large for the underlying hardware
watchpoint support. For example, each x86 debug register can watch up
to 4 bytes of memory, so trying to watch data structures whose size is
more than 16 bytes will cause GDB to use software
watchpoints.
-
The value of the expression to be watched depends on data held in
registers (as opposed to memory).
-
Too many different watchpoints requested. (On some architectures,
this situation is impossible to detect until the debugged program is
resumed.) Note that x86 debug registers are used both for hardware
breakpoints and for watchpoints, so setting too many hardware
breakpoints might cause watchpoint insertion to fail.
-
No hardware-assisted watchpoints provided by the target
implementation.
Software watchpoints are very slow, since GDB needs to
single-step the program being debugged and test the value of the
watched expression(s) after each instruction. The rest of this
section is mostly irrelevant for software watchpoints.
GDB uses several macros and primitives to support hardware
watchpoints:
TARGET_HAS_HARDWARE_WATCHPOINTS
- If defined, the target supports hardware watchpoints.
TARGET_CAN_USE_HARDWARE_WATCHPOINT (type, count, other)
- Return the number of hardware watchpoints of type type that are
possible to be set. The value is positive if count watchpoints
of this type can be set, zero if setting watchpoints of this type is
not supported, and negative if count is more than the maximum
number of watchpoints of type type that can be set. other
is non-zero if other types of watchpoints are currently enabled (there
are architectures which cannot set watchpoints of different types at
the same time).
TARGET_REGION_OK_FOR_HW_WATCHPOINT (addr, len)
- Return non-zero if hardware watchpoints can be used to watch a region
whose address is addr and whose length in bytes is len.
TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (size)
- Return non-zero if hardware watchpoints can be used to watch a region
whose size is size. GDB only uses this macro as a
fall-back, in case
TARGET_REGION_OK_FOR_HW_WATCHPOINT is not
defined.
TARGET_DISABLE_HW_WATCHPOINTS (pid)
- Disables watchpoints in the process identified by pid. This is
used, e.g., on HP-UX which provides operations to disable and enable
the page-level memory protection that implements hardware watchpoints
on that platform.
TARGET_ENABLE_HW_WATCHPOINTS (pid)
- Enables watchpoints in the process identified by pid. This is
used, e.g., on HP-UX which provides operations to disable and enable
the page-level memory protection that implements hardware watchpoints
on that platform.
target_insert_watchpoint (addr, len, type)
target_remove_watchpoint (addr, len, type)
- Insert or remove a hardware watchpoint starting at addr, for
len bytes. type is the watchpoint type, one of the
possible values of the enumerated data type
target_hw_bp_type,
defined by `breakpoint.h' as follows:
| | enum target_hw_bp_type
{
hw_write = 0, /* Common (write) HW watchpoint */
hw_read = 1, /* Read HW watchpoint */
hw_access = 2, /* Access (read or write) HW watchpoint */
hw_execute = 3 /* Execute HW breakpoint */
};
|
These two macros should return 0 for success, non-zero for failure.
target_remove_hw_breakpoint (addr, shadow)
target_insert_hw_breakpoint (addr, shadow)
- Insert or remove a hardware-assisted breakpoint at address addr.
Returns zero for success, non-zero for failure. shadow is the
real contents of the byte where the breakpoint has been inserted; it
is generally not valid when hardware breakpoints are used, but since
no other code touches these values, the implementations of the above
two macros can use them for their internal purposes.
target_stopped_data_address ()
- If the inferior has some watchpoint that triggered, return the address
associated with that watchpoint. Otherwise, return zero.
DECR_PC_AFTER_HW_BREAK
- If defined, GDB decrements the program counter by the value
of
DECR_PC_AFTER_HW_BREAK after a hardware break-point. This
overrides the value of DECR_PC_AFTER_BREAK when a breakpoint
that breaks is a hardware-assisted breakpoint.
HAVE_STEPPABLE_WATCHPOINT
- If defined to a non-zero value, it is not necessary to disable a
watchpoint to step over it.
HAVE_NONSTEPPABLE_WATCHPOINT
- If defined to a non-zero value, GDB should disable a
watchpoint to step the inferior over it.
HAVE_CONTINUABLE_WATCHPOINT
- If defined to a non-zero value, it is possible to continue the
inferior after a watchpoint has been hit.
CANNOT_STEP_HW_WATCHPOINTS
- If this is defined to a non-zero value, GDB will remove all
watchpoints before stepping the inferior.
STOPPED_BY_WATCHPOINT (wait_status)
- Return non-zero if stopped by a watchpoint. wait_status is of
the type
struct target_waitstatus, defined by `target.h'.