{"record":{"id":"e89981268d8452bc","repo":"go-delve/delve","slug":"wait-err-s-d","errorCode":null,"errorMessage":"wait err %s %d","messagePattern":"wait err (.+?) (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/native/proc_freebsd.go","lineNumber":350,"sourceCode":"\ttrapWaitNormal trapWaitMode = iota\n\ttrapWaitStepping\n)\n\n// Used by stop and trapWait\nfunc (dbp *nativeProcess) trapWaitInternal(pid int, mode trapWaitMode) (*nativeThread, error) {\n\tif dbp.os.selectedThread != nil {\n\t\tth := dbp.os.selectedThread\n\t\tdbp.os.selectedThread = nil\n\t\treturn th, nil\n\t}\n\tfor {\n\t\twpid, status, err := dbp.wait(pid, 0)\n\t\tif wpid != dbp.pid {\n\t\t\t// possibly a delayed notification from a process we just detached and killed, freebsd bug?\n\t\t\tcontinue\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"wait err %s %d\", err, pid)\n\t\t}\n\t\tif status.Killed() {\n\t\t\t// \"Killed\" status may arrive as a result of a Process.Kill() of some other process in\n\t\t\t// the system performed by the same tracer (e.g. in the previous test)\n\t\t\tcontinue\n\t\t}\n\t\tif status.Exited() {\n\t\t\tdbp.postExit()\n\t\t\treturn nil, proc.ErrProcessExited{Pid: wpid, Status: status.ExitStatus()}\n\t\t}\n\t\tif status.Signaled() {\n\t\t\t// Killed by a signal\n\t\t\tdbp.postExit()\n\t\t\treturn nil, proc.ErrProcessExited{Pid: wpid, Status: -int(status.Signal())}\n\t\t}\n\n\t\tvar info sys.PtraceLwpInfoStruct\n\t\tdbp.execPtraceFunc(func() { info, err = ptraceGetLwpInfo(wpid) })","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/proc_freebsd.go#L332-L368","documentation":"In FreeBSD's trapWaitInternal, dbp.wait(pid, 0) returned a non-nil error while the debugger waited for the traced process to hit a trap or exit. Delve wraps the raw wait(2)/wait4 error with the watched pid so the caller knows which process the kernel reported a problem for. It indicates the wait syscall itself failed rather than a normal stop event.","triggerScenarios":"nativeProcess.Launch/Attach/Continue flow on FreeBSD when trapWaitInternal calls dbp.wait(pid, 0) and the kernel returns an error, e.g. EINTR repeatedly, or the child pid is no longer a child of this tracer so wait4 returns ECHILD.","commonSituations":"The debugged process was already reaped by another process (double debugger attach, or a supervisor reaped it); the pid was killed between fork and wait; running under test harnesses that reap children; FreeBSD ptrace quirks after detach-and-kill of a previously traced process.","solutions":["Check whether another process (CI runner, supervisor) could have reaped or signaled the target; ensure only the debugger waits on the child pid.","Retry the operation; transient EINTR from signals delivered to the debugger is usually harmless on retry.","Verify the target pid still exists (ps / procstat) before attaching or continuing.","If it reproduces after detaching from another process, it matches the known FreeBSD delayed-notification quirk noted in the surrounding code; update FreeBSD or delve."],"exampleFix":"// before\ntgt, err := dbp.Continue()\nif err != nil { return err } // opaque 'wait err ...'\n\n// after\ntgt, err := dbp.Continue()\nvar exited proc.ErrProcessExited\nif errors.As(err, &exited) {\n    return nil // target already terminated, treat as clean exit\n}\nif err != nil { return err }","handlingStrategy":"retry","validationCode":"// before continuing/attaching on FreeBSD\nfunc pidWaitable(pid int) error {\n    out, err := exec.Command(\"ps\", \"-o\", \"ppid=\", \"-p\", strconv.Itoa(pid)).Output()\n    if err != nil { return fmt.Errorf(\"pid %d not present\", pid) }\n    _ = out\n    return nil\n}","typeGuard":null,"tryCatchPattern":"err := dbp.Continue()\nif err != nil && strings.HasPrefix(err.Error(), \"wait err \") {\n    // transient wait failure: verify target then retry once\n    if pidWaitable(pid) == nil {\n        err = dbp.Continue()\n    }\n}","preventionTips":["Ensure only one tracer waits on the child pid (no supervisor reaping).","Run debugger and target under the same user.","Retry Continue once on wait errors — many are transient EINTR.","Keep FreeBSD and delve updated for known ptrace quirks."],"tags":["freebsd","process-control","ptrace","wait-syscall"],"backgroundTag":"wait-syscall-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}