go-delve/delve · error

kinfo_getvmmap call failed

Error message

kinfo_getvmmap call failed

What it means

MemoryMap() on FreeBSD calls the C helper kinfo_getvmmap(C.kinfo_getvmmap) to fetch the process's vmmap entries. The error is returned when the C call returns a nil pointer, meaning the kernel did not produce the vm entry list for this pid (allocation failure or the kernel refused the sysctl). Because it comes from cgo, the underlying sysctl errno is lost and only this generic message surfaces.

Source

Thrown at pkg/proc/native/dump_freebsd.go:23

	"unsafe"

	"github.com/go-delve/delve/pkg/elfwriter"
	"github.com/go-delve/delve/pkg/proc"
)

/*
#include <sys/types.h>
#include <sys/user.h>
#include <libutil.h>
#include <stdlib.h>
*/
import "C"

func (p *nativeProcess) MemoryMap() ([]proc.MemoryMapEntry, error) {
	var cnt C.int
	vmentries := C.kinfo_getvmmap(C.int(p.pid), &cnt)
	if vmentries == nil {
		return nil, errors.New("kinfo_getvmmap call failed")
	}
	defer C.free(unsafe.Pointer(vmentries))
	r := make([]proc.MemoryMapEntry, 0, int(cnt))
	base := uintptr(unsafe.Pointer(vmentries))
	sz := unsafe.Sizeof(C.struct_kinfo_vmentry{})
	for i := 0; i < int(cnt); i++ {
		vmentry := (*C.struct_kinfo_vmentry)(unsafe.Pointer(base + sz*uintptr(i)))
		switch vmentry.kve_type {
		case C.KVME_TYPE_DEFAULT, C.KVME_TYPE_VNODE, C.KVME_TYPE_SWAP, C.KVME_TYPE_PHYS:
			r = append(r, proc.MemoryMapEntry{
				Addr: uint64(vmentry.kve_start),
				Size: uint64(vmentry.kve_end - vmentry.kve_start),

				Read:  vmentry.kve_protection&C.KVME_PROT_READ != 0,
				Write: vmentry.kve_protection&C.KVME_PROT_WRITE != 0,
				Exec:  vmentry.kve_protection&C.KVME_PROT_EXEC != 0,
			})
		}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Re-check that the target process is still alive (e.g. procfs/ps) and retry MemoryMap
  2. Verify FreeBSD kernel version supports kinfo_getvmmap (FreeBSD 9+ with KERN_VMSIGN sysctl)
  3. Check privileges: running inside a jail or with reduced capsicum rights may block vm sysctls; rerun with adequate rights
  4. If persistent, fall back to reading /proc/<pid>/map via procfs or gathering the map manually

Example fix

// before
vmentries := C.kinfo_getvmmap(C.int(p.pid), &cnt)
if vmentries == nil {
    return nil, errors.New("kinfo_getvmmap call failed")
}
// after
vmentries := C.kinfo_getvmmap(C.int(p.pid), &cnt)
if vmentries == nil {
    return nil, fmt.Errorf("kinfo_getvmmap call failed for pid %d (process may have exited or sysctl unavailable)", p.pid)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the process is alive before calling MemoryMap
if _, err := os.Stat(fmt.Sprintf("/proc/%d/status", pid)); os.IsNotExist(err) { // conceptually; on FreeBSD use ps or kill -0
    return nil, fmt.Errorf("pid %d no longer exists", pid)
}
if err := syscall.Kill(pid, 0); err != nil {
    return nil, fmt.Errorf("pid %d not signalable/alive: %w", pid, err)
}

Type guard

func memoryMapOK(entries []proc.MemoryMapEntry, err error) bool {
    return err == nil && len(entries) > 0
}

Try / catch

entries, err := proc.MemoryMap()
if err != nil {
    if strings.Contains(err.Error(), "kinfo_getvmmap call failed") {
        // target likely exited or sysctl unavailable: retry once or fall back
        time.Sleep(100 * time.Millisecond)
        entries, err = proc.MemoryMap()
    }
    if err != nil {
        return fmt.Errorf("memory map unavailable: %w", err)
    }
}

Prevention

When it happens

Trigger: Calling (*nativeProcess).MemoryMap() on FreeBSD when C.kinfo_getvmmap returns nil: the sysctl CTL_VM_VM_MAP KERN_VMSIGN get fails, user buffer allocation fails, or the target pid has exited/vanished mid-call.

Common situations: Dumping a core of a process that just died; running on a FreeBSD kernel lacking kinfo_getvmmap support (old kernels); restricted jail/capsicum environment blocking sysctl; memory pressure making calloc fail.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/532f5cf618f51aa9. Report an issue: GitHub.