{"record":{"id":"430084c37d0cd0dd","repo":"go-delve/delve","slug":"ep-variable-not-found","errorCode":null,"errorMessage":"ep variable not found","messagePattern":"ep variable not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/proc/stack_sigtramp.go","lineNumber":58,"sourceCode":"\t}\n\n\tgetctxaddr := func() (uint64, error) {\n\t\tctxvar := findvar(\"ctx\")\n\t\tif ctxvar == nil {\n\t\t\treturn 0, errors.New(\"ctx variable not found\")\n\t\t}\n\t\taddr, err := deref(ctxvar)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn addr, nil\n\t}\n\n\tswitch bi.GOOS {\n\tcase \"windows\":\n\t\tepvar := findvar(\"ep\")\n\t\tif epvar == nil {\n\t\t\treturn nil, errors.New(\"ep variable not found\")\n\t\t}\n\t\tepaddr, err := deref(epvar)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswitch bi.Arch.Name {\n\t\tcase \"amd64\":\n\t\t\treturn sigtrampContextWindowsAMD64(it.mem, epaddr)\n\t\tcase \"arm64\":\n\t\t\treturn sigtrampContextWindowsARM64(it.mem, epaddr)\n\t\tdefault:\n\t\t\treturn nil, errors.New(\"not implemented\")\n\t\t}\n\tcase \"linux\":\n\t\taddr, err := getctxaddr()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/stack_sigtramp.go#L40-L76","documentation":"On Windows, readSigtrampgoContext (pkg/proc/stack_sigtramp.go:58) recovers the interrupted thread's registers when stopped inside runtime.sigtrampgo by locating the local variable `ep` (a *exceptionpointers passed into sigtrampgo), dereferencing it, and walking to the CONTEXT structure. This error means no variable named `ep` was found in the frame's local scope, so Delve cannot decode the Windows exception context and unwind the stack through the signal handler.","triggerScenarios":"Raised when the debuggee is a Windows process stopped in runtime.sigtrampgo (e.g. after a Windows exception such as an access violation) and scope.Locals(0, \"ep\") finds nothing named `ep`. Causes: (1) the Go runtime binary lacks DWARF/DWARF-equivalent variable info for `ep` (stripped or highly optimized runtime); (2) binary/process mismatch on attach so the frame scope is resolved against wrong symbols; (3) the Go version's sigtrampgo no longer names the parameter `ep` while the installed Delve is older (or vice versa); (4) the stopped frame is misattributed (PC not actually in sigtrampgo).","commonSituations":"Debugging a Windows Go program that hit an access violation and the thread stops in the exception trampoline; attaching to a Windows process whose Go runtime was built stripped; running an older Delve against a newer Go release where sigtrampgo's signature/locals changed (Go 1.21+ changes to exception handling); core/exception debugging in IDEs via DAP on Windows.","solutions":["Upgrade Delve to the latest release so its expectations about sigtrampgo's `ep` parameter match your Go version.","Rebuild the program keeping symbol/debug info (avoid -ldflags=\"-s -w\"); unoptimized builds (-gcflags='all=-N -l') make locals reliably resolvable.","Ensure dlv attaches to a process built from exactly the binary it was given; relaunch via dlv exec to avoid symbol mismatch.","Continue past the exception or inspect thread state via `regs` as a workaround instead of unwinding through the trampoline.","If reproducible, file a Delve issue with Windows version, Go version, and --log-output=debug output."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// On Windows, before debugging, confirm symbol info is present and versions match:\n// go version -m <binary.exe>  (shows build flags; reject -ldflags=\"-s -w\" builds)\n// dlv version  vs  go version  (keep within supported range)","typeGuard":null,"tryCatchPattern":"try {\n    frames = client.Stacktrace(threadID, depth)\n} catch (err) {\n    if (strings.Contains(err.Error(), \"ep variable not found\")) {\n        // Windows sigtrampgo context unrecoverable; use raw regs or continue\n        regs, regErr := client.ListThreadRegs(threadID, false)\n        _ = regs\n        _ = regErr\n    } else {\n        return err\n    }\n}","preventionTips":["Keep debug info in Windows builds (no -s -w ldflags)","Update Delve whenever the Go toolchain changes sigtrampgo internals","Relaunch via dlv exec instead of attach when symbol mismatch is suspected","Reproduce exceptions in a test harness rather than debugging inside the trampoline"],"tags":["debugger","go","windows","signal-handling","dwarf"],"backgroundTag":"debug-variable-not-found","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}