{"record":{"id":"2dedbefd184e698a","repo":"go-delve/delve","slug":"parent-pointer-unreadable-w","errorCode":null,"errorMessage":"parent pointer unreadable: %w","messagePattern":"parent pointer unreadable: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/proc/variables.go","lineNumber":1325,"sourceCode":"\tt := v.RealType.(*godwarf.PtrType)\n\tv.Len = 1\n\n\tvar child *Variable\n\tif v.Unreadable == nil {\n\t\tptrval, err := readUintRaw(v.mem, v.Addr, t.ByteSize)\n\t\tif err == nil {\n\t\t\tchild = v.newVariable(\"\", ptrval, t.Type, DereferenceMemory(v.mem))\n\t\t} else {\n\t\t\t// We failed to read the pointer value; mark v as unreadable.\n\t\t\tv.Unreadable = err\n\t\t}\n\t}\n\n\tif v.Unreadable != nil {\n\t\t// Pointers get a child even if their value can't be read, to\n\t\t// maintain backwards compatibility.\n\t\tchild = v.newVariable(\"\", 0 /* addr */, t.Type, DereferenceMemory(v.mem))\n\t\tchild.Unreadable = fmt.Errorf(\"parent pointer unreadable: %w\", v.Unreadable)\n\t}\n\n\tv.Children = []Variable{*child}\n\tv.Value = constant.MakeUint64(v.Children[0].Addr)\n}\n\nfunc loadValues(vars []*Variable, cfg LoadConfig) {\n\tfor i := range vars {\n\t\tvars[i].loadValueInternal(0, cfg)\n\t}\n}\n\n// Extracts the value of the variable at the given address.\nfunc (v *Variable) loadValue(cfg LoadConfig) {\n\tv.loadValueInternal(0, cfg)\n}\n\nfunc (v *Variable) loadValueInternal(recurseLevel int, cfg LoadConfig) {","sourceCodeStart":1307,"sourceCodeEnd":1343,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/variables.go#L1307-L1343","documentation":"While loading a pointer variable, Delve could not dereference the pointer because the parent pointer's value itself was unreadable (e.g. its target address could not be read from memory). To keep the UI consistent (pointers always show a `*` child), Delve still creates a child variable and attaches this wrapped error as the child's `Unreadable` marker.","triggerScenarios":"Evaluating any pointer expression whose target memory is inaccessible: `print ptr`, `print ptr.field`, or hovering a pointer in an IDE; occurs when the pointed-to memory is unmapped or the process memory read fails during `maybeDereference`/`loadPointerTo`.","commonSituations":"Dangling pointers to freed/unmapped memory; inspecting core dumps where the pointed-to pages were not dumped; pointers read through a gdbserial connection to a stopped/dead target; corrupted register or stack values.","solutions":["Inspect the parent pointer's address value first (`print ptr`) and verify it points to valid memory.","Check why the parent pointer itself is unreadable (the wrapped `%w` error has the root cause).","For core dump debugging, re-dump with full memory (`gcore`/delve dump options) or debug the live process.","If the pointer is corrupted, inspect the code path that produced it."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Check the parent pointer's own Unreadable marker before dereferencing:\n// (dlv) print ptr          // see if value/address is sane\n// (dlv) print uintptr(ptr) // raw address","typeGuard":null,"tryCatchPattern":"// In DAP/RPC2 clients, inspect Variable.Unreadable instead of treating missing children as a crash:\nif v.Unreadable != nil {\n    log.Printf(\"pointer unreadable: %v\", v.Unreadable)\n}","preventionTips":["Check the wrapped root cause (%w) to understand why the parent was unreadable.","Inspect the pointer's raw address before dereferencing.","Use full-memory core dumps when post-mortem debugging pointer-heavy data.","Expect this on dangling/freed pointers; treat as diagnostic info, not a tool bug."],"tags":["debugger","go","pointer","memory-read"],"backgroundTag":"pointer-dereference-unreadable","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}