v2rayA/v2rayA · error

findProcessID: %w

Error message

findProcessID: %w

What it means

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.

Source

Thrown at service/common/netTools/netstat/netstat_unix.go:173

				PPID: ppid,
				Name: pn,
			}
			return s.Proc, nil
		}
	}
	return nil, SocketFreedErr
}

/*
没有做缓存,每次调用都会扫描,消耗资源
*/

var ErrorNotFound = fmt.Errorf("process not found")

func findProcessID(pname string) (pids []string, err error) {
	f, err := os.ReadDir(pathProc)
	if err != nil {
		err = fmt.Errorf("findProcessID: %w", err)
		return
	}
loop1:
	for _, fi := range f {
		if !fi.IsDir() {
			continue
		}
		fn := fi.Name()
		for _, t := range fn {
			if t > '9' || t < '0' {
				continue loop1
			}
		}
		if pn, _ := getProcessInfo(fn); pn == pname {
			pids = append(pids, fn)
		}
	}
	if len(pids) > 0 {

View on GitHub (pinned to 71e5442fc5)

Solutions

  1. Unwrap the error (errors.Unwrap / %w chain) to see the real *fs.PathError and its errno (EACCES, ENOENT).
  2. Run the lookup with sufficient privileges or relax /proc permissions (hidepid) so the service user can list /proc.
  3. Ensure /proc is mounted in the runtime environment (containers) before calling the netstat functions.
  4. Guard the environment first: os.Stat("/proc") and os.ReadDir("/proc") sanity check, or build-tag platform-specific code properly.

Example fix

// before
ok, err := netstat.IsProcessListenPort("nginx", 80)
if err != nil { log.Fatal(err) } // opaque without unwrap
// after
ok, err := netstat.IsProcessListenPort("nginx", 80)
if err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) { log.Fatalf("proc access %s: %v", pe.Path, pe.Err) }
}
Defensive patterns

Strategy: validation

Validate before calling

func procReadable() error {
    if _, err := os.ReadDir("/proc"); err != nil {
        return fmt.Errorf("/proc not listable: %w", err)
    }
    return nil
}

Type guard

func canEnumerateProc() bool {
    _, err := os.ReadDir("/proc")
    return err == nil
}

Try / catch

pids, err := findProcessID("myapp") // via IsProcessListenPort
if err != nil {
    if errors.Is(err, netstat.ErrorNotFound) { return false, nil }
    var pe *fs.PathError
    if errors.As(err, &pe) {
        log.Fatalf("proc access denied at %s: %v", pe.Path, pe.Err)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of v2rayA/v2rayA@71e5442fc5 (2026-09-05). Data as JSON: /api/errors/8a4c76e55b7d5083. Report an issue: GitHub.