{"record":{"id":"532f5cf618f51aa9","repo":"go-delve/delve","slug":"kinfo-getvmmap-call-failed","errorCode":null,"errorMessage":"kinfo_getvmmap call failed","messagePattern":"kinfo_getvmmap call failed","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/native/dump_freebsd.go","lineNumber":23,"sourceCode":"\t\"unsafe\"\n\n\t\"github.com/go-delve/delve/pkg/elfwriter\"\n\t\"github.com/go-delve/delve/pkg/proc\"\n)\n\n/*\n#include <sys/types.h>\n#include <sys/user.h>\n#include <libutil.h>\n#include <stdlib.h>\n*/\nimport \"C\"\n\nfunc (p *nativeProcess) MemoryMap() ([]proc.MemoryMapEntry, error) {\n\tvar cnt C.int\n\tvmentries := C.kinfo_getvmmap(C.int(p.pid), &cnt)\n\tif vmentries == nil {\n\t\treturn nil, errors.New(\"kinfo_getvmmap call failed\")\n\t}\n\tdefer C.free(unsafe.Pointer(vmentries))\n\tr := make([]proc.MemoryMapEntry, 0, int(cnt))\n\tbase := uintptr(unsafe.Pointer(vmentries))\n\tsz := unsafe.Sizeof(C.struct_kinfo_vmentry{})\n\tfor i := 0; i < int(cnt); i++ {\n\t\tvmentry := (*C.struct_kinfo_vmentry)(unsafe.Pointer(base + sz*uintptr(i)))\n\t\tswitch vmentry.kve_type {\n\t\tcase C.KVME_TYPE_DEFAULT, C.KVME_TYPE_VNODE, C.KVME_TYPE_SWAP, C.KVME_TYPE_PHYS:\n\t\t\tr = append(r, proc.MemoryMapEntry{\n\t\t\t\tAddr: uint64(vmentry.kve_start),\n\t\t\t\tSize: uint64(vmentry.kve_end - vmentry.kve_start),\n\n\t\t\t\tRead:  vmentry.kve_protection&C.KVME_PROT_READ != 0,\n\t\t\t\tWrite: vmentry.kve_protection&C.KVME_PROT_WRITE != 0,\n\t\t\t\tExec:  vmentry.kve_protection&C.KVME_PROT_EXEC != 0,\n\t\t\t})\n\t\t}","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/dump_freebsd.go#L5-L41","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-check that the target process is still alive (e.g. procfs/ps) and retry MemoryMap","Verify FreeBSD kernel version supports kinfo_getvmmap (FreeBSD 9+ with KERN_VMSIGN sysctl)","Check privileges: running inside a jail or with reduced capsicum rights may block vm sysctls; rerun with adequate rights","If persistent, fall back to reading /proc/<pid>/map via procfs or gathering the map manually"],"exampleFix":"// before\nvmentries := C.kinfo_getvmmap(C.int(p.pid), &cnt)\nif vmentries == nil {\n    return nil, errors.New(\"kinfo_getvmmap call failed\")\n}\n// after\nvmentries := C.kinfo_getvmmap(C.int(p.pid), &cnt)\nif vmentries == nil {\n    return nil, fmt.Errorf(\"kinfo_getvmmap call failed for pid %d (process may have exited or sysctl unavailable)\", p.pid)\n}","handlingStrategy":"try-catch","validationCode":"// ensure the process is alive before calling MemoryMap\nif _, err := os.Stat(fmt.Sprintf(\"/proc/%d/status\", pid)); os.IsNotExist(err) { // conceptually; on FreeBSD use ps or kill -0\n    return nil, fmt.Errorf(\"pid %d no longer exists\", pid)\n}\nif err := syscall.Kill(pid, 0); err != nil {\n    return nil, fmt.Errorf(\"pid %d not signalable/alive: %w\", pid, err)\n}","typeGuard":"func memoryMapOK(entries []proc.MemoryMapEntry, err error) bool {\n    return err == nil && len(entries) > 0\n}","tryCatchPattern":"entries, err := proc.MemoryMap()\nif err != nil {\n    if strings.Contains(err.Error(), \"kinfo_getvmmap call failed\") {\n        // target likely exited or sysctl unavailable: retry once or fall back\n        time.Sleep(100 * time.Millisecond)\n        entries, err = proc.MemoryMap()\n    }\n    if err != nil {\n        return fmt.Errorf(\"memory map unavailable: %w\", err)\n    }\n}","preventionTips":["Check the target is alive (kill -0 / ps) before dumping its memory map","Run with sufficient privileges and outside restrictive jails/capsicum sandboxes","Retry MemoryMap once after a short sleep; vmmap reads race with process exit","Pin to a FreeBSD version known to support kinfo_getvmmap"],"tags":["freebsd","cgo","memory-map","process-exited"],"backgroundTag":"kinfo-getvmmap-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}