{"record":{"id":"3f9de69f6c9060c2","repo":"go-delve/delve","slug":"kinfo-getproc-failed-v","errorCode":null,"errorMessage":"kinfo_getproc failed: %v","messagePattern":"kinfo_getproc failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/native/proc_freebsd.go","lineNumber":196,"sourceCode":"\t\tpid := int(proc.ki_pid)\n\t\tif _, isseen := seen[pid]; isseen {\n\t\t\tcontinue\n\t\t}\n\t\tseen[pid] = struct{}{}\n\n\t\targv := strings.Join(getCmdLineInternal(ps, proc), \" \")\n\t\tlog.Debugf(\"waitfor: new process %q\", argv)\n\t\tif strings.HasPrefix(argv, pfx) {\n\t\t\treturn pid, nil\n\t\t}\n\t}\n\treturn 0, nil\n}\n\nfunc initialize(dbp *nativeProcess) (string, error) {\n\tkp, err := C.kinfo_getproc(C.int(dbp.pid))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"kinfo_getproc failed: %v\", err)\n\t}\n\tdefer C.free(unsafe.Pointer(kp))\n\n\tcomm := C.GoString(&kp.ki_comm[0])\n\tdbp.os.comm = strings.ReplaceAll(string(comm), \"%\", \"%%\")\n\n\treturn getCmdLine(dbp.pid), nil\n}\n\n// kill kills the target process.\nfunc (procgrp *processGroup) kill(dbp *nativeProcess) (err error) {\n\tif ok, _ := dbp.Valid(); !ok {\n\t\treturn nil\n\t}\n\tdbp.execPtraceFunc(func() {\n\t\tfor _, th := range dbp.threads {\n\t\t\tptraceResume(th.ID)\n\t\t}","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/proc_freebsd.go#L178-L214","documentation":"During initialization on FreeBSD, Delve fetches the process's kinfo_proc via C.kinfo_getproc to learn the command name (ki_comm). If that C call errors — typically because the process no longer exists — initialize returns \"kinfo_getproc failed: %v\". Without this info the target cannot be fully initialized.","triggerScenarios":"proc.Attach/initialize on FreeBSD when kinfo_getproc(C.int(dbp.pid)) fails: the pid is gone or never existed, or the caller lacks permission to query it.","commonSituations":"Attaching to a pid that exited between discovery and attach; typo in the pid; attaching to another user's process without privileges; FreeBSD kern.terminating processes not yet reaped.","solutions":["Verify the pid exists: `ps -p <pid>` — if gone, find the new pid and reattach.","Run dlv as the process owner (or root) if permission is the issue.","Attach quickly after obtaining the pid to avoid the exit race.","Check `sysctl kern.ptrace` restrictions if ps shows the process but attach still fails."],"exampleFix":"// before\ndlv attach 4242   // pid already exited\n// after\nps aux | grep myapp        # get live pid\ndlv attach $(pgrep myapp)","handlingStrategy":"validation","validationCode":"out, err := exec.Command(\"ps\", \"-o\", \"pid=,user=\", \"-p\", strconv.Itoa(pid)).Output()\nif err != nil {\n    return fmt.Errorf(\"pid %d does not exist or is not visible\", pid)\n}\nowner := strings.TrimSpace(strings.Fields(string(out))[1])\nif owner != currentUser() {\n    return fmt.Errorf(\"pid %d owned by %s; insufficient permission\", pid, owner)\n}","typeGuard":null,"tryCatchPattern":"comm, err := initialize(dbp)\nif err != nil && strings.Contains(err.Error(), \"kinfo_getproc failed\") {\n    // re-resolve the pid; the process likely exited between discovery and attach\n}","preventionTips":["Look up the pid immediately before attaching.","Attach as the process owner or root when crossing users.","Confirm with `ps -p` before every attach.","Script attach flows to re-resolve pids after process restarts."],"tags":["freebsd","attach","process-lookup","kinfo"],"backgroundTag":"process-not-found","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}