go-delve/delve · error
hardware breakpoints exhausted
Error message
hardware breakpoints exhausted
What it means
DebugRegisters.SetBreakpoint programs one of the x86 hardware debug registers (DR0-DR3). CPUs only provide four hardware breakpoints, so pAddrs has length 4; requesting an index >= 4 means all debug registers would be exhausted. Delve throws this instead of silently reusing or evicting an existing hardware breakpoint.
Source
Thrown at pkg/proc/amd64util/debugregs.go:63
case 0x0:
sz = 1
case 0x1:
sz = 2
case 0x2:
sz = 8 // sic
case 0x3:
sz = 4
}
return addr, read, write, sz
}
// SetBreakpoint sets hardware breakpoint at index 'idx' to the specified
// address, read/write flags and size.
// If the breakpoint is already in use but the parameters match it does
// nothing.
func (drs *DebugRegisters) SetBreakpoint(idx uint8, addr uint64, read, write bool, sz int) error {
if int(idx) >= len(drs.pAddrs) {
return errors.New("hardware breakpoints exhausted")
}
curaddr, curread, curwrite, cursz := drs.breakpoint(idx)
if curaddr != 0 {
if (curaddr != addr) || (curread != read) || (curwrite != write) || (cursz != sz) {
return fmt.Errorf("hardware breakpoint %d already in use (address %#x)", idx, curaddr)
}
// hardware breakpoint already set
return nil
}
if read && !write {
return errors.New("break on read only not supported")
}
*(drs.pAddrs[idx]) = addr
var lenrw uint64
if write {
lenrw |= 0x1View on GitHub (pinned to a23773e6c3)
Solutions
- Reduce the number of simultaneous hardware breakpoints to at most 4 per thread
- Clear unused hardware breakpoints (ClearBreakpoint/zeroing the debug register) before setting new ones
- Fall back to software breakpoints for the extra locations
- Check the return error of SetBreakpoint and surface 'watchpoint limit reached' to the user instead of retrying
Example fix
// before
drs.SetBreakpoint(4, addr, false, true, 8) // panics into error: exhausted
// after
const maxHW = 4
if idx >= maxHW { return fmt.Errorf("watchpoint limit reached (max %d)", maxHW) }
drs.SetBreakpoint(uint8(idx), addr, false, true, 8) Defensive patterns
Strategy: validation
Validate before calling
const maxHWBreakpoints = 4
if idx >= maxHWBreakpoints {
return fmt.Errorf("hardware breakpoint limit is %d, cannot set index %d", maxHWBreakpoints, idx)
} Try / catch
if err := drs.SetBreakpoint(idx, addr, read, write, sz); err != nil {
if err.Error() == "hardware breakpoints exhausted" {
// fall back to software breakpoint
}
} Prevention
- Track how many hardware breakpoints are armed per thread before adding one
- Clear watchpoints when done — don't leave DR0-DR3 programmed
- Cap UI watchpoint creation at 4 and explain the CPU limit
When it happens
Trigger: Calling SetBreakpoint (directly or via proc's hardware breakpoint support) with idx >= len(drs.pAddrs), e.g. setting a 5th watchpoint/hardware breakpoint on a single thread while the previous four are still armed.
Common situations: Setting more than 4 simultaneous watchpoints in a debug session; watchpoints leaked across threads/iterations because they were never cleared; users expecting unlimited watchpoints like software breakpoints.
Related errors
- break on read only not supported
- ErrCouldNotDetermineRelocation
- errBinaryInfoClose
- could not decode first frame
- unable to find function context
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/3488b2ffaa982b80.
Report an issue: GitHub.