{"record":{"id":"480efd7f7bee36dc","repo":"go-delve/delve","slug":"wrong-number-of-bytes-for-register-s-d-480efd","errorCode":null,"errorMessage":"wrong number of bytes for register %s (%d)","messagePattern":"wrong number of bytes for register (.+?) \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/linutil/regs_amd64_arch.go","lineNumber":203,"sourceCode":"\tcase regnum.AMD64_R11:\n\t\tp = &r.Regs.R11\n\tcase regnum.AMD64_R12:\n\t\tp = &r.Regs.R12\n\tcase regnum.AMD64_R13:\n\t\tp = &r.Regs.R13\n\tcase regnum.AMD64_R14:\n\t\tp = &r.Regs.R14\n\tcase regnum.AMD64_R15:\n\t\tp = &r.Regs.R15\n\tcase regnum.AMD64_Rip:\n\t\tp = &r.Regs.Rip\n\tcase regnum.AMD64_Rflags:\n\t\tp = &r.Regs.Eflags\n\t}\n\n\tif p != nil {\n\t\tif reg.Bytes != nil && len(reg.Bytes) != 8 {\n\t\t\treturn false, 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\treturn false, nil\n\t}\n\n\tif r.loadFpRegs != nil {\n\t\terr := r.loadFpRegs(r)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tr.loadFpRegs = nil\n\t}\n\n\tif regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 {\n\t\treturn false, fmt.Errorf(\"can not set %s\", regnum.AMD64ToName(regNum))\n\t}\n\n\treg.FillBytes()","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/linutil/regs_amd64_arch.go#L185-L221","documentation":"SetReg validates that register values supplied by callers carry exactly 8 bytes before writing them into the amd64 ptrace register set. A register whose byte slice has a length other than 8 is inconsistent with the fixed 64-bit width of general-purpose amd64 registers, so SetReg refuses to write it rather than corrupting process state.","triggerScenarios":"Calling proc.SetReg on a Linux/amd64 thread with a Variable representing a general-purpose register (e.g. Rax, Rip, Rflags) whose reg.Bytes slice is non-nil but has length != 8.","commonSituations":"Clients building register Variables by hand from protocol data (e.g. RPC layer passing partial/truncated register bytes), or frontend tools that fill only some bytes of a register before issuing a register-set request.","solutions":["Ensure reg.Bytes is exactly 8 bytes long before calling SetReg (or leave Bytes nil and set Uint64Val, letting reg.FillBytes() handle it)","Call reg.FillBytes() on the Variable to normalize the byte slice before invoking SetReg","Check the caller (RPC client / API layer) for register payloads that were truncated or serialized incorrectly"],"exampleFix":"// before\nreg.Bytes = []byte{0x01, 0x02} // 2 bytes\nthread.SetReg(regnum.AMD64_Rax, reg)\n// after\nreg.Bytes = nil\nreg.Uint64Val = 0x1234\nreg.FillBytes() // produces 8 bytes\nthread.SetReg(regnum.AMD64_Rax, reg)","handlingStrategy":"validation","validationCode":"if reg.Bytes != nil && len(reg.Bytes) != 8 {\n    return fmt.Errorf(\"register %s requires exactly 8 bytes, got %d\", regnum.AMD64ToName(regNum), len(reg.Bytes))\n}\nreg.FillBytes()","typeGuard":"func isValidGPRBytes(reg *proc.Variable) bool {\n    return reg.Bytes == nil || len(reg.Bytes) == 8\n}","tryCatchPattern":"if err := thread.SetReg(regNum, reg); err != nil {\n    if strings.Contains(err.Error(), \"wrong number of bytes\") {\n        reg.FillBytes()\n        err = thread.SetReg(regNum, reg)\n    }\n    return err\n}","preventionTips":["Always call FillBytes() on register Variables before SetReg","Never hand-craft register byte slices; set Uint64Val and let the library normalize","Validate register payloads at API boundaries (RPC clients) before sending"],"tags":["go","registers","amd64","ptrace"],"backgroundTag":"register-byte-size-mismatch","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}