{"record":{"id":"a6d4e483dd73f967","repo":"go-delve/delve","slug":"ptracegetlwpinfo-err-s-d","errorCode":null,"errorMessage":"ptraceGetLwpInfo err %s %d","messagePattern":"ptraceGetLwpInfo err (.+?) (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/native/proc_freebsd.go","lineNumber":370,"sourceCode":"\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) })\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"ptraceGetLwpInfo err %s %d\", err, pid)\n\t\t}\n\t\ttid := int(info.Lwpid)\n\t\tpl_flags := int(info.Flags)\n\t\tth, ok := dbp.threads[tid]\n\t\tif ok {\n\t\t\tth.Status = (*waitStatus)(status)\n\t\t}\n\n\t\tif status.StopSignal() == sys.SIGTRAP {\n\t\t\tif pl_flags&_PL_FLAG_EXITED != 0 {\n\t\t\t\tdelete(dbp.threads, tid)\n\t\t\t\tdbp.execPtraceFunc(func() { err = ptraceCont(tid, 0) })\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t} else if pl_flags&_PL_FLAG_BORN != 0 {\n\t\t\t\tth, err = dbp.addThread(int(tid), false)","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/proc_freebsd.go#L352-L388","documentation":"After a successful wait on FreeBSD, trapWaitInternal asks the kernel for ptrace(PT_LWPINFO) details of the stopped light-weight process (thread). When PT_LWPINFO fails, delve wraps the error with the pid being debugged. This means the stop event was received but the thread metadata could not be fetched, so the stop cannot be fully processed.","triggerScenarios":"ptraceGetLwpInfo(wpid) returns an error right after wait reports a stop — typically because the LWP exited between the wait and the PT_LWPINFO call (ESRCH), or because wpid is no longer traceable by this process.","commonSituations":"Racy thread death during heavy multithreaded debugging; attaching while threads are being created/destroyed; running as a different user than the target (ptrace permission checks); hardened kernels/JS Chebyshev with restricted ptrace scope.","solutions":["Retry the Continue/step; the error is often a benign race with a dying thread.","Ensure the debugger runs as the same user as the target (or root) and that ptrace is permitted (kern.securelevel, MAC policy).","Reduce thread churn in the debugged program if reproducible, and capture the underlying errno to confirm ESRCH.","Update FreeBSD/delve if PT_LWPINFO persistently fails for valid stops."],"exampleFix":"// before\nerr := dbp.Continue() // fails: ptraceGetLwpInfo err ESRCH 1234\n\n// after\nerr := dbp.Continue()\nif err != nil && strings.Contains(err.Error(), \"ptraceGetLwpInfo err\") {\n    // a thread died during the stop; re-list threads and retry once\n    err = dbp.Continue()\n}","handlingStrategy":"retry","validationCode":"// confirm ptrace permission and target liveness before debugging on FreeBSD\nfunc canTrace(pid int) error {\n    if _, err := os.Stat(fmt.Sprintf(\"/proc/%d/status\", pid)); err == nil {\n        return nil\n    }\n    return exec.Command(\"ps\", \"-p\", strconv.Itoa(pid)).Run()\n}","typeGuard":null,"tryCatchPattern":"err := dbp.Continue()\nif err != nil && strings.Contains(err.Error(), \"ptraceGetLwpInfo err\") {\n    // thread died between wait and PT_LWPINFO: re-list threads and retry\n    err = dbp.Continue()\n}","preventionTips":["Run as same user or root so PT_LWPINFO is permitted.","Treat ESRCH-ish failures as benign thread-death races and retry.","Avoid attaching while the target is in heavy thread create/destroy loops.","Log the underlying errno to distinguish permission vs race causes."],"tags":["freebsd","ptrace","threads","lwp"],"backgroundTag":"ptrace-lwpinfo-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}