go-delve/delve · error
break on read only not supported
Error message
break on read only not supported
What it means
SetBreakpoint rejects watchpoints configured with read=true and write=false. The x86 debug register RW encoding supports execute, write-only, or read/write — a pure read-only watchpoint cannot be expressed, so Delve fails fast rather than silently widening the watchpoint to read/write.
Source
Thrown at pkg/proc/amd64util/debugregs.go:75
// 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 |= 0x1
}
if read {
lenrw |= 0x2
}
switch sz {
case 1:
// already ok
case 2:
lenrw |= 0x1 << 2
case 4:
lenrw |= 0x3 << 2
case 8:View on GitHub (pinned to a23773e6c3)
Solutions
- Request read+write (read=true, write=true) instead of read-only — x86 supports the combined mode
- Use a write-only watchpoint if reads don't matter
- Emulate read-only watching with software breakpoints on the code paths that read the variable
- Reject read-only watchpoints in the client UI before sending them to the backend
Example fix
// before err := drs.SetBreakpoint(0, addr, true, false, 8) // error // after err := drs.SetBreakpoint(0, addr, true, true, 8) // read/write watchpoint, accepted
Defensive patterns
Strategy: validation
Validate before calling
func validateWatchpoint(read, write bool) error {
if read && !write {
return errors.New("x86 supports execute, write, or read+write watchpoints only")
}
return nil
} Try / catch
if err := drs.SetBreakpoint(idx, addr, read, write, sz); err != nil {
if strings.Contains(err.Error(), "break on read only not supported") {
// retry with read+write or surface unsupported-watchpoint to user
}
} Prevention
- Never request read-only data watchpoints on x86 backends
- Default watchpoint UIs to read/write when the user selects 'read'
- Document the x86 DR7 RW-encoding limitation in client code
When it happens
Trigger: Calling SetBreakpoint(idx, addr, true /*read*/, false /*write*/, sz), e.g. asking for a data watchpoint that triggers only on memory reads.
Common situations: Users setting 'watch -r' style read-only watchpoints via the terminal or RPC and expecting x86 to support it; porting watchpoint code from debuggers whose backends emulate read-only watching.
Related errors
- hardware breakpoints exhausted
- runtime.copystack has too many return instructions
- can not watch %q
- ErrCouldNotDetermineRelocation
- errBinaryInfoClose
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/bb3852233b325b44.
Report an issue: GitHub.