{"record":{"id":"924d2050747154d5","repo":"go-delve/delve","slug":"hardware-breakpoints-exhausted-924d20","errorCode":null,"errorMessage":"hardware breakpoints exhausted","messagePattern":"hardware breakpoints exhausted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/native/threads_linux_arm64.go","lineNumber":152,"sourceCode":"\t\treturn nil, nil\n\t}\n\n\tfor _, bp := range t.dbp.Breakpoints().M {\n\t\tif bp.WatchType != 0 && siginfo.addr >= bp.Addr && siginfo.addr < bp.Addr+uint64(bp.WatchType.Size()) {\n\t\t\treturn bp, nil\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"could not find hardware breakpoint for address %#x\", siginfo.addr)\n}\n\nfunc (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {\n\twpstate, err := t.getWatchpoints()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif idx >= wpstate.num {\n\t\treturn errors.New(\"hardware breakpoints exhausted\")\n\t}\n\n\tconst (\n\t\treadBreakpoint  = 0x1\n\t\twriteBreakpoint = 0x2\n\t\tlenBitOffset    = 5\n\t\ttypeBitOffset   = 3\n\t\tprivBitOffset   = 1\n\t)\n\n\tvar typ uint64\n\tif wtype.Read() {\n\t\ttyp |= readBreakpoint\n\t}\n\tif wtype.Write() {\n\t\ttyp |= writeBreakpoint\n\t}\n","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/threads_linux_arm64.go#L134-L170","documentation":"ARM64 hardware breakpoints/watchpoints are a finite resource (the count is read from the HW debug registers via getWatchpoints, wpstate.num, typically 6 breakpoints / 4 watchpoints). writeHardwareBreakpoint refuses to program slot `idx` when idx >= wpstate.num, meaning all available hardware slots are exhausted or an invalid index was requested.","triggerScenarios":"Setting a hardware breakpoint or watchpoint (writeHardwareBreakpoint) when the requested slot index exceeds the number of available hardware breakpoint registers reported by the kernel on arm64 Linux.","commonSituations":"Setting more hardware watchpoints than the CPU supports (commonly 4 on arm64); creating many `watch` commands with hardware backing; running on hardware with fewer debug registers (e.g. some ARM cores expose fewer).","solutions":["Delete existing hardware breakpoints/watchpoints to free a slot before adding new ones.","Convert some watchpoints to software breakpoints (regular breakpoints) which are unlimited.","Check available hardware slots: `cat /proc/sys/debug/` or delve's watchpoint count on the target machine.","If more watchpoints are needed, use a machine/kernel with more debug registers or use page-protection-based alternatives."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// query available hardware breakpoint slots before setting more\nmaxBp := readHWBreakpointCount() // e.g. from ID_AA64MDR0_EL1 / kernel, typically 6\nif activeHWBreakpoints >= maxBp {\n\treturn errors.New(\"no free hardware breakpoint slots\")\n}","typeGuard":"func isHWBreakpointsExhausted(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"hardware breakpoints exhausted\")\n}","tryCatchPattern":"err := dlv.CreateWatchpoint(addr, size, write)\nif err != nil && strings.Contains(err.Error(), \"hardware breakpoints exhausted\") {\n\t// fall back to a software breakpoint\n\treturn dlv.CreateBreakpoint(addr)\n}","preventionTips":["Track how many hardware watchpoints (usually 4 on arm64) are active before adding more.","Remove unused hardware breakpoints/watchpoints promptly.","Fall back to software breakpoints when hardware slots run out.","Check the target CPU's debug-register count on constrained ARM hardware."],"tags":["arm64","hardware-breakpoints","watchpoints","linux"],"backgroundTag":"hardware-breakpoints-exhausted","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}