{"record":{"id":"8b35e9ecdb9e37bc","repo":"go-delve/delve","slug":"escape-check-for-s-failed-variable-unreadable","errorCode":null,"errorMessage":"escape check for %s failed, variable unreadable: %v","messagePattern":"escape check for (.+?) failed, variable unreadable: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/fncall.go","lineNumber":737,"sourceCode":"\nfunc funcCallArgRegABI(fn *Function, bi *BinaryInfo, entry reader.Variable, argname string, typ godwarf.Type, pargFrameSize *int64) (*funcCallArg, error) {\n\t// Conservatively calculate the full stack argument space for ABI0.\n\t*pargFrameSize = alignAddr(*pargFrameSize, typ.Align())\n\t*pargFrameSize += typ.Size()\n\n\tisret, _ := entry.Val(dwarf.AttrVarParam).(bool)\n\treturn &funcCallArg{name: argname, typ: typ, dwarfEntry: entry.Tree, isret: isret}, nil\n}\n\n// alignAddr rounds up addr to a multiple of align. Align must be a power of 2.\nfunc alignAddr(addr, align int64) int64 {\n\treturn (addr + align - 1) &^ (align - 1)\n}\n\n// allPointers calls f on every pointer contained in v\nfunc allPointers(v *Variable, name string, f func(addr uint64, name string) error) error {\n\tif v.Unreadable != nil {\n\t\treturn fmt.Errorf(\"escape check for %s failed, variable unreadable: %v\", name, v.Unreadable)\n\t}\n\tswitch v.Kind {\n\tcase reflect.Ptr, reflect.UnsafePointer:\n\t\tvar w *Variable\n\t\tif len(v.Children) == 1 {\n\t\t\t// this branch is here to support pointers constructed with typecasts from ints or the '&' operator\n\t\t\tw = &v.Children[0]\n\t\t} else {\n\t\t\tw = v.maybeDereference()\n\t\t}\n\t\treturn f(w.Addr, name)\n\tcase reflect.Chan, reflect.String, reflect.Slice:\n\t\treturn f(v.Base, name)\n\tcase reflect.Map:\n\t\tsv := v.clone()\n\t\tsv.RealType = godwarf.ResolveTypedef(&(v.RealType.(*godwarf.MapType).TypedefType))\n\t\tsv = sv.maybeDereference()\n\t\treturn f(sv.Addr, name)","sourceCodeStart":719,"sourceCodeEnd":755,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/fncall.go#L719-L755","documentation":"allPointers walks an actual argument variable to check pointer escape, but if the variable itself (or a child) is Unreadable — memory could not be read, or the value couldn't be loaded — the escape check cannot proceed and this error is returned, aborting the call injection.","triggerScenarios":"Calling a function whose argument's memory is unreadable at check time: freed/unmapped memory, invalid pointer constructed by cast, register-based value not yet materialized, or unreadable children during the recursive walk.","commonSituations":"Arguments built from stale pointers, values living in registers of a stopped thread that can't be read, or corrupted heap during debugging of a crashing program.","solutions":["Print the argument first to confirm it is readable before calling","Fix/refresh the pointer so it refers to valid live memory","Disable the escape check if the value is provably safe but unreadable to the checker"],"exampleFix":"// before\ncall Use(p) // p unreadable -> escape check fails\n// after\nprint p       // verify readable first\ncall Use(*p)","handlingStrategy":"validation","validationCode":"v, err := scope.EvalExpression(expr, loadCfg)\nif err != nil || v.Unreadable != nil {\n    return errors.New(\"argument not readable; fix pointer/memory before call injection\")\n}","typeGuard":"func readable(v *proc.Variable) bool { return v != nil && v.Unreadable == nil }","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"variable unreadable\") {\n    // inspect the argument first, or retry after the target advances to valid state\n}","preventionTips":["print each pointer argument before injecting a call to confirm readability","Avoid arguments built from stale or dangling pointers"],"tags":["go","debugger","escape-analysis","unreadable-memory","call-injection"],"backgroundTag":"variable-unreadable","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}