{"record":{"id":"b586eb58ec507c3d","repo":"go-delve/delve","slug":"could-not-get-event-message-s","errorCode":null,"errorMessage":"could not get event message: %s","messagePattern":"could not get event message: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/native/proc_linux.go","lineNumber":518,"sourceCode":"\t\t\t}\n\t\t\t// does this ever happen?\n\t\t\tdelete(dbp.threads, wpid)\n\t\t\tcontinue\n\t\t}\n\t\tif status.StopSignal() == sys.SIGTRAP && (status.TrapCause() == sys.PTRACE_EVENT_CLONE || status.TrapCause() == sys.PTRACE_EVENT_VFORK) {\n\t\t\t// A traced thread has cloned a new thread, grab the pid and\n\t\t\t// add it to our list of traced threads.\n\t\t\t// If TrapCause() is sys.PTRACE_EVENT_VFORK this is actually a new\n\t\t\t// process, but treat it as a normal thread until exec happens, so that\n\t\t\t// we can initialize the new process normally.\n\t\t\tvar cloned uint\n\t\t\tdbp.execPtraceFunc(func() { cloned, err = sys.PtraceGetEventMsg(wpid) })\n\t\t\tif err != nil {\n\t\t\t\tif err == sys.ESRCH {\n\t\t\t\t\t// thread died while we were adding it\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"could not get event message: %s\", err)\n\t\t\t}\n\t\t\tth, err = dbp.addThread(int(cloned), false)\n\t\t\tif err != nil {\n\t\t\t\tif err == sys.ESRCH {\n\t\t\t\t\t// thread died while we were adding it\n\t\t\t\t\tdelete(dbp.threads, int(cloned))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif halt {\n\t\t\t\tth.os.running = false\n\t\t\t\tdbp.threads[int(wpid)].os.running = false\n\t\t\t\treturn nil, nil\n\t\t\t}\n\t\t\tif err = th.resume(); err != nil {\n\t\t\t\tif err == sys.ESRCH {\n\t\t\t\t\t// thread died while we were adding it","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/proc_linux.go#L500-L536","documentation":"This error is returned by the Linux native backend's wait loop (trapWaitInternal) when PTRACE_GETEVENTMSG fails for a stopped thread that has hit a PTRACE_EVENT_CLONE or PTRACE_EVENT_VFORK stop. Delve needs the event message to learn the pid/tid of the newly cloned thread so it can attach to it; if the ptrace call fails with anything other than ESRCH (thread already gone, which is tolerated), the wait is aborted with this wrapped error. It almost always indicates the tracee died or the ptrace relationship was lost mid-event.","triggerScenarios":"A debugged thread hits a clone/vfork stop and Delve calls sys.PtraceGetEventMsg(wpid), but the call fails with an errno other than ESRCH — e.g. the tracee was killed between the stop and the call, the process was re-parented, or another debugger/tool interfered with the ptrace attachment.","commonSituations":"Debugging a multithreaded program under heavy thread churn where threads are killed while the debugger processes stops; running inside containers or sandboxes (seccomp/apparmor) that restrict ptrace; attaching to a process that another tracer simultaneously owns (only one tracer allowed, causing EPERM-style failures).","solutions":["Check no other tracer (strace, another dlv, IDE debugger) is attached to the target; only one PTRACE_ATTACH is permitted.","Verify ptrace permissions: ensure /proc/sys/kernel/yama/ptrace_scope allows the attach and the container has CAP_SYS_PTRACE (docker run --cap-add=SYS_PTRACE).","Make sure the target process is still alive; if threads are being killed rapidly, reduce thread churn or attach to a quiescent process.","Retry the debug session; if reproducible, file an issue with the wrapped errno string since it indicates an unexpected ptrace failure."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before debugging, verify single-tracer and ptrace access\nps -o tracer= -p $PID 2>/dev/null && echo 'already traced'\ntest -r /proc/$PID/mem || echo 'no ptrace permission'\ncat /proc/sys/kernel/yama/ptrace_scope","typeGuard":null,"tryCatchPattern":"err := runDebugSession()\nif err != nil && strings.Contains(err.Error(), \"could not get event message\") {\n    // target likely died mid-clone; verify liveness and retry once\n    if processAlive(pid) { retrySession(pid) }\n}","preventionTips":["Never run two tracers (dlv + strace) on the same pid","Grant CAP_SYS_PTRACE when debugging inside containers","Avoid killing threads in the target while a debug session is active","Keep yama ptrace_scope at 0 or 1 for same-user debugging"],"tags":["linux","ptrace","debugger","process-management"],"backgroundTag":"ptrace-geteventmsg-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}