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

  1. Request read+write (read=true, write=true) instead of read-only — x86 supports the combined mode
  2. Use a write-only watchpoint if reads don't matter
  3. Emulate read-only watching with software breakpoints on the code paths that read the variable
  4. 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

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


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/bb3852233b325b44. Report an issue: GitHub.