{"record":{"id":"95dcd6f24ea846d2","repo":"go-delve/delve","slug":"nil-pointer-dereference","errorCode":null,"errorMessage":"nil pointer dereference","messagePattern":"nil pointer dereference","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/eval.go","lineNumber":2333,"sourceCode":"\t}\n\n\tif len(xev.Children) == 1 {\n\t\t// this branch is here to support pointers constructed with typecasts from ints\n\t\txev.Children[0].OnlyAddr = false\n\t\tstack.push(&(xev.Children[0]))\n\t\treturn\n\t}\n\txev.loadPtr()\n\tif xev.Unreadable != nil {\n\t\tval, ok := constant.Uint64Val(xev.Value)\n\t\tif ok && val == 0 {\n\t\t\tstack.err = fmt.Errorf(\"couldn't read pointer: %w\", xev.Unreadable)\n\t\t\treturn\n\t\t}\n\t}\n\trv := &xev.Children[0]\n\tif rv.Addr == 0 {\n\t\tstack.err = errors.New(\"nil pointer dereference\")\n\t\treturn\n\t}\n\tstack.push(rv)\n}\n\n// Evaluates expressions &<subexpr>\nfunc (scope *EvalScope) evalAddrOf(op *evalop.AddrOf, stack *evalStack) {\n\txev := stack.pop()\n\tif xev.Addr == 0 || xev.DwarfType == nil {\n\t\tstack.err = fmt.Errorf(\"can not take address of %q\", astutil.ExprToString(op.Node.X))\n\t\treturn\n\t}\n\n\tstack.push(xev.pointerToVariable())\n}\n\nfunc (v *Variable) pointerToVariable() *Variable {\n\tv.OnlyAddr = true","sourceCodeStart":2315,"sourceCodeEnd":2351,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/eval.go#L2315-L2351","documentation":"After evalPointerDeref loads the pointee, the child variable's address (rv.Addr) is 0 — meaning the pointee has no readable backing memory (nil or zero-valued pointer produced without an address). Delve refuses to push an unaddressable pointee and throws 'nil pointer dereference'. This differs from error 68: the pointer expression was not the nilVariable sentinel, but its dereferenced child still has no address.","triggerScenarios":"Dereferencing a pointer constructed from an integer cast (e.g., *(*int)(unsafe.Pointer(uintptr(0)))) or a pointer variable read as 0 from memory where the nilVariable sentinel check did not trigger; DAP/RPC clients expanding a pointer child whose pointee address is 0.","commonSituations":"Inspecting pointers cast from ints in low-level code; pointer fields zeroed by the program but represented as non-sentinel variables; corrupted memory reads yielding base 0.","solutions":["Verify the pointer is non-nil before dereferencing: print ptr or print ptr != nil.","If the pointer came from an integer cast, cast a valid address (e.g. obtained via &x) instead of 0.","Step past initialization so the pointer holds a real address.","In tooling, check the dereferenced child's Addr == 0 and display '<nil>' gracefully rather than propagating the error."],"exampleFix":"// before\nprint *(*T)(unsafe.Pointer(uintptr(p))) // p == 0\n// after\ncondition guard: \"p != 0\" then\nprint *(*T)(unsafe.Pointer(uintptr(p)))","handlingStrategy":"type-guard","validationCode":"pv, _ := scope.EvalExpression(ptrExpr, cfg)\nif pv != nil && pv.Kind == reflect.Ptr && pv.Base == 0 {\n    return fmt.Errorf(\"%s holds a nil/invalid address\", ptrExpr)\n}","typeGuard":"func hasPointeeAddress(child *proc.Variable) bool {\n    return child != nil && child.Addr != 0\n}","tryCatchPattern":"_, err := scope.EvalExpression(\"*\"+ptrExpr, cfg)\nif err != nil && strings.Contains(err.Error(), \"nil pointer dereference\") {\n    return fmt.Errorf(\"%s points to nothing (addr 0)\", ptrExpr)\n}","preventionTips":["Avoid dereferencing pointers cast from integer values unless the address is known valid","Check the pointee child's Addr != 0 before expanding pointer children in DAP/RPC clients","Treat zero-base pointer variables as nil in tooling","Set breakpoints after pointer initialization to inspect valid pointees"],"tags":["go","debugger","nil-pointer","dereference"],"backgroundTag":"nil-pointer-dereference","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}