{"record":{"id":"24e8dd6d02ea0626","repo":"go-delve/delve","slug":"error-while-waiting-after-adding-thread-d-s","errorCode":null,"errorMessage":"error while waiting after adding thread: %d %s","messagePattern":"error while waiting after adding thread: (.+?) (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/native/proc_linux.go","lineNumber":376,"sourceCode":"\t\t\t// Do not return err if err == EPERM,\n\t\t\t// we may already be tracing this thread due to\n\t\t\t// PTRACE_O_TRACECLONE. We will surely blow up later\n\t\t\t// if we truly don't have permissions.\n\t\t\treturn nil, fmt.Errorf(\"could not attach to new thread %d %s\", tid, err)\n\t\t}\n\t\tpid, status, err := dbp.waitFast(tid)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif status.Exited() {\n\t\t\treturn nil, fmt.Errorf(\"thread already exited %d\", pid)\n\t\t}\n\t}\n\n\tdbp.execPtraceFunc(func() { err = syscall.PtraceSetOptions(tid, ptraceOptions) })\n\tif err == syscall.ESRCH {\n\t\tif _, _, err = dbp.waitFast(tid); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error while waiting after adding thread: %d %s\", tid, err)\n\t\t}\n\t\tdbp.execPtraceFunc(func() { err = syscall.PtraceSetOptions(tid, ptraceOptions) })\n\t\tif err == syscall.ESRCH {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"could not set options for new traced thread %d %s\", tid, err)\n\t\t}\n\t}\n\n\tdbp.threads[tid] = &nativeThread{\n\t\tID:  tid,\n\t\tdbp: dbp,\n\t\tos:  new(osSpecificDetails),\n\t}\n\tif dbp.memthread == nil {\n\t\tdbp.memthread = dbp.threads[tid]\n\t}","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/proc_linux.go#L358-L394","documentation":"When PtraceSetOptions fails with ESRCH (thread not found — often because the stop notification from attach hasn't been consumed yet), Delve calls waitFast(tid) to settle the thread before retrying. This error means that recovery wait itself failed, so the new thread's ptrace options could not be configured.","triggerScenarios":"addThread: syscall.PtraceSetOptions returned ESRCH, then dbp.waitFast(tid) returned an error (e.g. ECHILD because the thread was reaped elsewhere or isn't a child, ESRCH because the thread vanished, EINTR not retried) while setting options for a newly attached thread.","commonSituations":"Attaching to processes with heavy thread creation/destruction where the TID disappears between attach and SetOptions; ptrace event wait races in multi-process (follow-exec) debugging; older kernels with non-standard wait semantics under containers.","solutions":["Retry the attach operation; the race is usually transient.","Check that the target process is still alive and the TID still exists in /proc/<pid>/task/.","If debugging via container runtimes, ensure the debugger runs in the same PID namespace and has CAP_SYS_PTRACE.","Avoid attaching to processes currently being traced or reaped by another tool (strace, another dlv instance)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// confirm the TID is still live before option setup\ndead, err := os.Stat(fmt.Sprintf(\"/proc/%d/task/%d\", pid, tid))\nif err != nil || dead == nil {\n    return fmt.Errorf(\"thread %d vanished, rescan thread list\", tid)\n}","typeGuard":"func isWaitAfterAddErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"error while waiting after adding thread\")\n}","tryCatchPattern":"err := updateThreadList()\nif isWaitAfterAddErr(err) {\n    time.Sleep(10 * time.Millisecond)\n    err = updateThreadList() // retry once; races are usually transient\n}","preventionTips":["Ensure the debugger shares the PID namespace with the target (same container or host PID namespace)","Grant CAP_SYS_PTRACE in containerized environments","Avoid concurrent tracers (strace + dlv) on the same process","Retry thread-list refresh on transient failures"],"tags":["linux","ptrace","waitpid","race-condition"],"backgroundTag":"waitpid-esrch","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}