{"record":{"id":"8a4c76e55b7d5083","repo":"v2rayA/v2rayA","slug":"findprocessid-w","errorCode":null,"errorMessage":"findProcessID: %w","messagePattern":"findProcessID: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/common/netTools/netstat/netstat_unix.go","lineNumber":173,"sourceCode":"\t\t\t\tPPID: ppid,\n\t\t\t\tName: pn,\n\t\t\t}\n\t\t\treturn s.Proc, nil\n\t\t}\n\t}\n\treturn nil, SocketFreedErr\n}\n\n/*\n没有做缓存，每次调用都会扫描，消耗资源\n*/\n\nvar ErrorNotFound = fmt.Errorf(\"process not found\")\n\nfunc findProcessID(pname string) (pids []string, err error) {\n\tf, err := os.ReadDir(pathProc)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"findProcessID: %w\", err)\n\t\treturn\n\t}\nloop1:\n\tfor _, fi := range f {\n\t\tif !fi.IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\tfn := fi.Name()\n\t\tfor _, t := range fn {\n\t\t\tif t > '9' || t < '0' {\n\t\t\t\tcontinue loop1\n\t\t\t}\n\t\t}\n\t\tif pn, _ := getProcessInfo(fn); pn == pname {\n\t\t\tpids = append(pids, fn)\n\t\t}\n\t}\n\tif len(pids) > 0 {","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/v2rayA/v2rayA/blob/71e5442fc548c05680ee55eae943e6c0afe9ac51/service/common/netTools/netstat/netstat_unix.go#L155-L191","documentation":"findProcessID wraps any failure of os.ReadDir(\"/proc\") as 'findProcessID: %w', preserving the underlying permission/OS error. Unlike ProcOpenFailedErr (used by FillProcesses), this path keeps the cause, so unwrapping reveals whether it was a permission denial, missing /proc, or another filesystem error.","triggerScenarios":"IsProcessListenPort -> findProcessID on a host where /proc cannot be enumerated: hidepid=2 mount, read-protected /proc, chroot without procfs, or non-procfs Unix despite the linux build tag.","commonSituations":"Hardened servers with /proc restricted to root while the service runs unprivileged; minimal containers without procfs mounted; running the binary on macOS/BSD (file is guarded by // +build linux plan9 freebsd solaris) where /proc doesn't exist.","solutions":["Unwrap the error (errors.Unwrap / %w chain) to see the real *fs.PathError and its errno (EACCES, ENOENT).","Run the lookup with sufficient privileges or relax /proc permissions (hidepid) so the service user can list /proc.","Ensure /proc is mounted in the runtime environment (containers) before calling the netstat functions.","Guard the environment first: os.Stat(\"/proc\") and os.ReadDir(\"/proc\") sanity check, or build-tag platform-specific code properly."],"exampleFix":"// before\nok, err := netstat.IsProcessListenPort(\"nginx\", 80)\nif err != nil { log.Fatal(err) } // opaque without unwrap\n// after\nok, err := netstat.IsProcessListenPort(\"nginx\", 80)\nif err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) { log.Fatalf(\"proc access %s: %v\", pe.Path, pe.Err) }\n}","handlingStrategy":"validation","validationCode":"func procReadable() error {\n    if _, err := os.ReadDir(\"/proc\"); err != nil {\n        return fmt.Errorf(\"/proc not listable: %w\", err)\n    }\n    return nil\n}","typeGuard":"func canEnumerateProc() bool {\n    _, err := os.ReadDir(\"/proc\")\n    return err == nil\n}","tryCatchPattern":"pids, err := findProcessID(\"myapp\") // via IsProcessListenPort\nif err != nil {\n    if errors.Is(err, netstat.ErrorNotFound) { return false, nil }\n    var pe *fs.PathError\n    if errors.As(err, &pe) {\n        log.Fatalf(\"proc access denied at %s: %v\", pe.Path, pe.Err)\n    }\n    return err\n}","preventionTips":["Unwrap the error: unlike ProcOpenFailedErr, this path preserves the real OS error via %w.","Check /proc permissions (hidepid=2 blocks non-root listing of other users' processes).","Verify the runtime platform actually has procfs — this file is linux-tagged but errors cryptically elsewhere.","Run pre-flight os.ReadDir(\"/proc\") checks in health/setup code."],"tags":["linux","procfs","permissions","error-wrapping"],"backgroundTag":"proc-not-accessible","analyzedSha":"71e5442fc548c05680ee55eae943e6c0afe9ac51","analyzedAt":"2026-09-05T20:04:37.459Z","contentChangedAt":"2026-09-05T20:04:37.459Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}