{"record":{"id":"e2cc174b4040ca6d","repo":"go-delve/delve","slug":"can-not-set-register-s","errorCode":null,"errorMessage":"can not set register %s","messagePattern":"can not set register (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/winutil/regs_amd64_arch.go","lineNumber":339,"sourceCode":"\t\tp = &ctx.R13\n\tcase regnum.AMD64_R14:\n\t\tp = &ctx.R14\n\tcase regnum.AMD64_R15:\n\t\tp = &ctx.R15\n\tcase regnum.AMD64_Rip:\n\t\tp = &ctx.Rip\n\t}\n\n\tif p != nil {\n\t\tif reg.Bytes != nil && len(reg.Bytes) != 8 {\n\t\t\treturn fmt.Errorf(\"wrong number of bytes for register %s (%d)\", regnum.AMD64ToName(regNum), len(reg.Bytes))\n\t\t}\n\t\t*p = reg.Uint64Val\n\t} else if regNum == regnum.AMD64_Rflags {\n\t\tctx.EFlags = uint32(reg.Uint64Val)\n\t} else {\n\t\tif regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 {\n\t\t\treturn fmt.Errorf(\"can not set register %s\", regnum.AMD64ToName(regNum))\n\t\t}\n\t\treg.FillBytes()\n\t\tif len(reg.Bytes) > 16 {\n\t\t\treturn fmt.Errorf(\"too many bytes when setting register %s\", regnum.AMD64ToName(regNum))\n\t\t}\n\t\tcopy(ctx.FltSave.XmmRegisters[(regNum-regnum.AMD64_XMM0)*16:], reg.Bytes)\n\t}\n\treturn nil\n}\n","sourceCodeStart":321,"sourceCodeEnd":349,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/winutil/regs_amd64_arch.go#L321-L349","documentation":"On Windows amd64, only general-purpose registers (via CONTEXT pointer) and Rflags are directly settable; other register numbers are accepted only if they fall in the XMM0..XMM0+15 range. Any other register number (e.g. debug registers, segment selectors, FPU control regs) cannot be set and yields this error.","triggerScenarios":"Attempting to set a register by number outside the GP + Rflags + XMM sets on a Windows/amd64 target — e.g. trying to write a debug register (DR0-DR7), segment registers, or ST/MMX registers through SetRegs.","commonSituations":"Tooling that sets register state generically across platforms (Linux allows some registers Windows doesn't); restoring full register contexts including x87 state; attempting to write DR registers for hardware breakpoints.","solutions":["Restrict writes to GP registers, Rflags, and XMM0-XMM15 on Windows/amd64; skip others gracefully","Use the Windows debug API (SetThreadContext with proper CONTEXT flags) directly for DR/segment registers outside Delve","Set a hardware breakpoint via Delve's breakpoint API instead of writing debug registers","Check regnum values before calling: reject AMD64_XMM0..+15 only, or GP, else no-op"],"exampleFix":"// before\nsetReg(regnum.AMD64_Dr0, val) // can not set register DR0\n// after\nif (regNum >= regnum.AMD64_Rax && regNum <= regnum.AMD64_R15) || regNum == regnum.AMD64_Rip ||\n   (regNum >= regnum.AMD64_XMM0 && regNum <= regnum.AMD64_XMM0+15) {\n    setReg(regNum, val)\n}\n","handlingStrategy":"validation","validationCode":"// Whitelist settable registers on Windows amd64 before writing\nsettable := func(n regnum.REGNUM) bool {\n    gp := n >= regnum.AMD64_Rax && n <= regnum.AMD64_Rip\n    xmm := n >= regnum.AMD64_XMM0 && n <= regnum.AMD64_XMM0+15\n    return gp || xmm\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never attempt DR/segment/x87 register writes through Delve on Windows","Use Delve's breakpoint API for hardware breakpoints instead of DR registers","Check the porting notes (Documentation/internal/portnotes.md) for per-OS register support"],"tags":["delve","windows","registers","amd64"],"backgroundTag":"register-set-unsupported","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}