{"record":{"id":"c521fc7b381ac2eb","repo":"go-delve/delve","slug":"read-out-of-bounds","errorCode":null,"errorMessage":"read out of bounds","messagePattern":"read out of bounds","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/mem.go","lineNumber":181,"sourceCode":"\t\t\t\tbinary.LittleEndian.PutUint64(buf, piece.Val)\n\t\t\t}\n\t\t\tcmem.data = append(cmem.data, buf[:piece.Size]...)\n\t\tdefault:\n\t\t\tpanic(\"unsupported piece kind\")\n\t\t}\n\t}\n\tpaddingBytes := int(size) - len(cmem.data)\n\tif paddingBytes > 0 && paddingBytes < arch.ptrSize {\n\t\tpadding := make([]byte, paddingBytes)\n\t\tcmem.data = append(cmem.data, padding...)\n\t}\n\treturn cmem, nil\n}\n\nfunc (mem *compositeMemory) ReadMemory(data []byte, addr uint64) (int, error) {\n\taddr -= mem.base\n\tif addr >= uint64(len(mem.data)) || addr+uint64(len(data)) > uint64(len(mem.data)) {\n\t\treturn 0, errors.New(\"read out of bounds\")\n\t}\n\tcopy(data, mem.data[addr:addr+uint64(len(data))])\n\treturn len(data), nil\n}\n\nfunc (mem *compositeMemory) WriteMemory(addr uint64, data []byte) (int, error) {\n\taddr -= mem.base\n\tif addr >= uint64(len(mem.data)) || addr+uint64(len(data)) > uint64(len(mem.data)) {\n\t\treturn 0, errors.New(\"write out of bounds\")\n\t}\n\tif mem.regs.ChangeFunc == nil {\n\t\tfor _, piece := range mem.pieces {\n\t\t\tif piece.Kind == op.RegPiece {\n\t\t\t\treturn 0, errors.New(\"can not write registers\")\n\t\t\t}\n\t\t}\n\t}\n","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/mem.go#L163-L199","documentation":"compositeMemory backs variables whose bytes come from registers and/or cached memory slices. ReadMemory adjusts the address by the memory base and rejects any read that falls outside the assembled data buffer with 'read out of bounds'. It indicates the requested address/size range is not covered by the pieces (registers or memory slices) that make up this composite view.","triggerScenarios":"Any expression evaluation that reads a variable backed by compositeMemory (e.g. a struct assembled from register pieces or a stack-frame-relative variable) where addr or addr+len(data) exceeds the collected data — e.g. evaluating a variable whose DWARF location resolves outside the frame, or reading past the end of a register-assembled value.","commonSituations":"Stale frame references after the stack changed (evaluating a variable in a returned frame); DWARF location lists mismatching the binary; reading variables in optimized code where Delve mis-assembles pieces; core dumps with missing memory regions.","solutions":["Re-select the correct goroutine/frame (frame number 0 or a still-live frame) and re-evaluate the variable","Rebuild the binary with -gcflags=\"all=-N -l\" to disable optimizations that produce fragmented locations","If using a core dump, verify it matches the exact binary build; retry evaluation after stepping so the frame is live"],"exampleFix":"// before (dlv)\n(dlv) frame 7\n(dlv) print localVar   // read out of bounds\n// after\n(dlv) frame 0\n(dlv) print localVar","handlingStrategy":"validation","validationCode":"// In the debugger, confirm the frame is live before evaluating:\n//   (dlv) frame 0\n//   (dlv) print localVar\n// Reads from returned frames trigger out-of-bounds on composite memory.","typeGuard":null,"tryCatchPattern":"v, err := eval(expr)\nif err != nil && strings.Contains(err.Error(), \"read out of bounds\") {\n    return fmt.Errorf(\"variable %s is not available in this frame (optimized or dead frame): %w\", expr, err)\n}","preventionTips":["Evaluate variables only in the current live frame","Build with -gcflags=\"all=-N -l\" for reliable variable locations","Match core dumps exactly to the binary build"],"tags":["go","memory","registers","dwarf"],"backgroundTag":"memory-read-out-of-bounds","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}