go-delve/delve · error
procstat_open_sysctl failed: %v
Error message
procstat_open_sysctl failed: %v
What it means
nativeProcess.EntryPoint on FreeBSD calls libprocstat's procstat_open_sysctl() to obtain a handle on kernel process information. If that open fails, delve reports 'procstat_open_sysctl failed'. Without this handle the entry point (AT_ENTRY from the auxiliary vector) cannot be located.
Source
Thrown at pkg/proc/native/proc_freebsd.go:586
return pickedTrapThread, nil
}
// Used by Detach
func (dbp *nativeProcess) detach(kill bool) error {
if !kill {
for _, th := range dbp.threads {
ptraceResume(th.ID)
}
}
return ptraceDetach(dbp.pid)
}
// EntryPoint returns the entry point address of the process.
func (dbp *nativeProcess) EntryPoint() (uint64, error) {
ps, err := C.procstat_open_sysctl()
if err != nil {
return 0, fmt.Errorf("procstat_open_sysctl failed: %v", err)
}
defer C.procstat_close(ps)
var count C.uint
kipp, err := C.procstat_getprocs(ps, C.KERN_PROC_PID, C.int(dbp.pid), &count)
if err != nil {
return 0, fmt.Errorf("procstat_getprocs failed: %v", err)
}
defer C.procstat_freeprocs(ps, kipp)
if count == 0 {
return 0, errors.New("procstat_getprocs returned no processes")
}
auxv, err := C.procstat_getauxv(ps, kipp, &count)
if err != nil {
return 0, fmt.Errorf("procstat_getauxv failed: %v", err)
}
defer C.procstat_freeauxv(ps, auxv)View on GitHub (pinned to a23773e6c3)
Solutions
- Run delve as root (or the same user as the target) so kernel process metadata is readable.
- Verify the target pid exists: procstat -a | grep <pid>.
- Check you are on a FreeBSD version whose libprocstat supports procstat_getauxv (FreeBSD 12+); otherwise entry-point lookup cannot work.
- As a workaround, read AT_ENTRY from the binary's auxv via other means or set breakpoints at explicit addresses.
Example fix
// before
ep, err := dbp.EntryPoint() // procstat_open_sysctl failed: ...
// after
ep, err := dbp.EntryPoint()
if err != nil {
// fall back to ELF entry if procstat is unavailable
if f, ferr := elf.Open(exePath); ferr == nil {
ep = f.Entry
}
} Defensive patterns
Strategy: fallback
Validate before calling
// FreeBSD: verify procstat availability before relying on EntryPoint
func procstatAvailable() bool {
return exec.Command("procstat", "-a").Run() == nil
} Try / catch
ep, err := proc.EntryPoint()
if err != nil && strings.Contains(err.Error(), "procstat_open_sysctl failed") {
// fall back to ELF entry point
if f, ferr := elf.Open(exePath); ferr == nil {
ep, err = f.Entry, nil
f.Close()
}
} Prevention
- Run as root or the target's owner for kernel metadata access.
- Verify FreeBSD 12+ (procstat_getauxv dependency).
- Confirm the pid is alive before entry-point lookups.
- Provide an ELF-entry fallback in tooling that needs the entry address.
When it happens
Trigger: Calling EntryPoint (directly or via debugger APIs that need the entry address, e.g. setting breakpoints at process start) on FreeBSD when procstat_open_sysctl fails — typically due to kernel metadata (kvm) access restrictions.
Common situations: Running as unprivileged user with restricted access to kernel process data (security.bsd.see_other_uids, jail/ Capsicum restrictions); FreeBSD versions lacking the procstat auxv API; delve built against mismatched libprocstat headers.
Related errors
- procstat_getprocs failed: %v
- procstat_getauxv failed: %v
- procstat_getprocs returned no processes
- kinfo_getvmmap call failed
- entry point not found
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/79537fcb34d5d037.
Report an issue: GitHub.