{"record":{"id":"698aaf84d5047202","repo":"go-delve/delve","slug":"could-not-read-d-bytes-from-register-d-size-d-698aaf","errorCode":null,"errorMessage":"could not read %d bytes from register %d (size: %d)","messagePattern":"could not read (.+?) bytes from register (.+?) \\(size: (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/mem.go","lineNumber":146,"sourceCode":"\t}\n\treturn cm, err\n}\n\nfunc newCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece, size int64) (*compositeMemory, error) {\n\tcmem := &compositeMemory{realmem: mem, arch: arch, regs: regs, pieces: pieces, data: []byte{}}\n\tfor i := range pieces {\n\t\tpiece := &pieces[i]\n\t\tswitch piece.Kind {\n\t\tcase op.RegPiece:\n\t\t\treg := regs.Bytes(piece.Val)\n\t\t\tif piece.Size == 0 && i == len(pieces)-1 {\n\t\t\t\tpiece.Size = len(reg)\n\t\t\t}\n\t\t\tif piece.Size > len(reg) {\n\t\t\t\tif regs.FloatLoadError != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"could not read %d bytes from register %d (size: %d), also error loading floating point registers: %v\", piece.Size, piece.Val, len(reg), regs.FloatLoadError)\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"could not read %d bytes from register %d (size: %d)\", piece.Size, piece.Val, len(reg))\n\t\t\t}\n\t\t\tcmem.data = append(cmem.data, reg[:piece.Size]...)\n\t\tcase op.AddrPiece:\n\t\t\tbuf := make([]byte, piece.Size)\n\t\t\tif _, err := mem.ReadMemory(buf, piece.Val); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"could not read %d bytes from address %#x: %v\", piece.Size, piece.Val, err)\n\t\t\t}\n\t\t\tcmem.data = append(cmem.data, buf...)\n\t\tcase op.ImmPiece:\n\t\t\tbuf := piece.Bytes\n\t\t\tif buf == nil {\n\t\t\t\tsz := max(piece.Size, 8)\n\t\t\t\tif piece.Size == 0 && i == len(pieces)-1 {\n\t\t\t\t\tpiece.Size = arch.PtrSize() // DWARF doesn't say what this should be\n\t\t\t\t}\n\t\t\t\tbuf = make([]byte, sz)\n\t\t\t\tbinary.LittleEndian.PutUint64(buf, piece.Val)\n\t\t\t}","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/mem.go#L128-L164","documentation":"The plain variant of the composite-memory register read failure: a DWARF piece asks for piece.Size bytes from register piece.Val but the register buffer only has len(reg) bytes. Unlike error 550, FloatLoadError is nil, so the mismatch is in the DWARF expression vs. the actual register width, not a failed FP load.","triggerScenarios":"CreateCompositeMemory on a location expression where a RegisterPiece's declared size (piece.Size, explicitly set in the DWARF or by the caller) is larger than the width of the register as reported by regs.Bytes — e.g. size overridden to a value that assumes a wider vector register, or reading a 128-bit piece from a 64-bit GPR.","commonSituations":"DWARF produced by compilers targeting vector types in registers on architectures Delve maps to narrower register buffers; stale binary vs. different-architecture debugger host; hand-crafted or mismatched core dump register sets.","solutions":["Verify the debugged binary architecture matches the debugger/arch tags; rebuild with the correct GOARCH.","Check whether the DWARF producer emitted a piece size larger than the register width (e.g. DW_OP_piece 16 on a GPR) — recompile with a current toolchain.","Update Delve so regs.Bytes maps vector registers (SSE/NEON) to their full width.","If the variable lives in a vector register unsupported by this backend, inspect its memory location instead (force it to spill, e.g. print via pointer)."],"exampleFix":"// before: mismatched arch\nGOARCH=arm64 dlv exec ./amd64-binary   // register widths disagree with DWARF\n// after\nGOARCH=amd64 dlv exec ./amd64-binary","handlingStrategy":"validation","validationCode":"// Verify arch match and piece sizes before evaluating DWARF register pieces\nif runtime.GOARCH != binaryArch { return errors.New(\"debugger arch mismatch with binary\") }\nfor _, p := range pieces {\n    if p.Size > len(regs.Bytes(p.Val)) { return fmt.Errorf(\"piece on reg %d requests %d > %d bytes\", p.Val, p.Size, len(regs.Bytes(p.Val))) }\n}","typeGuard":"func registerPieceReadable(regs proc.Registers, regnum, size int) bool {\n    return size >= 0 && size <= len(regs.Bytes(uint64(regnum)))\n}","tryCatchPattern":"if err := tryEval(v); err != nil {\n    var re *RegisterReadError // or string match\n    if strings.Contains(err.Error(), \"could not read \") {\n        v.Unreadable = err.Error(); return nil\n    }\n    return err\n}","preventionTips":["Match debugger GOARCH/OS to the target binary exactly.","Rebuild binaries with a current Go toolchain to avoid malformed DW_OP_piece sizes.","Avoid manual core-dump/register manipulations that shrink the register set.","Update Delve when debugging binaries using vector types in registers."],"tags":["dwarf","registers","debugging","delve"],"backgroundTag":"register-read-too-short","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}