{"record":{"id":"662dad41a3ed4707","repo":"go-delve/delve","slug":"failed-to-get-xstate-v","errorCode":null,"errorMessage":"failed to get xstate: %v","messagePattern":"failed to get xstate: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/native/ptrace_freebsd_amd64.go","lineNumber":53,"sourceCode":"\tif xsaveLen > 0 {\n\t\treturn xsaveLen, nil\n\t}\n\tif xsaveLen < 0 {\n\t\treturn xsaveLen, fmt.Errorf(\"failed to get xstate info: %v\", xsaveErr)\n\t}\n\treturn ptraceGetXsaveLen(tid)\n}\n\n// ptraceGetXsave gets the X86 XSAVE data for the given tid.\nfunc ptraceGetXsave(tid int) ([]byte, error) {\n\tlen, err := ptraceXsaveLen(tid)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\txsaveBuf := make([]byte, len)\n\tret, err := C.ptrace(C.PT_GETXSTATE, C.pid_t(tid), C.caddr_t(unsafe.Pointer(&xsaveBuf[0])), C.int(len))\n\tif ret != 0 {\n\t\treturn nil, fmt.Errorf(\"failed to get xstate: %v\", err)\n\t}\n\treturn xsaveBuf, nil\n}\n\n// ptraceSetXsave sets the X86 XSAVE data for the given tid.\nfunc ptraceSetXsave(tid int, xsaveBuf []byte) error {\n\tret, err := C.ptrace(C.PT_SETXSTATE, C.pid_t(tid), C.caddr_t(unsafe.Pointer(&xsaveBuf[0])), C.int(len(xsaveBuf)))\n\tif ret != 0 {\n\t\treturn fmt.Errorf(\"failed to set xstate: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc ptraceGetRegset(id int) (*amd64util.AMD64Xstate, error) {\n\tvar regset amd64util.AMD64Xstate\n\tret, err := C.ptrace(C.PT_GETFPREGS, C.pid_t(id), C.caddr_t(unsafe.Pointer(&regset.AMD64PtraceFpRegs)), C.int(0))\n\tif ret != 0 {\n\t\treturn nil, fmt.Errorf(\"failed to get FP registers: %v\", err)","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/ptrace_freebsd_amd64.go#L35-L71","documentation":"ptraceGetXsave issues PT_GETXSTATE via cgo ptrace(2) on FreeBSD/amd64 to read the thread's extended XSAVE area (XMM/YMM state). When the syscall returns non-zero, the raw errno is wrapped in this message. Note the message prints err, which is often nil after a failing cgo ptrace call, so the %v may render as an unhelpful value.","triggerScenarios":"Any call chain that reads full registers of a FreeBSD amd64 thread (ptraceGetRegset -> ptraceGetXsave) when PT_GETXSTATE fails: the thread exited between attach and the call, the tid is invalid, or the kernel/CPU does not support the XSTATE ptrace interface (old FreeBSD or CPU lacking XSAVE).","commonSituations":"Debugging on FreeBSD <9/old kernels without PT_GETXSTATE; running on VMs/CPUs with XSAVE disabled; thread died mid-debug-session so tid is stale; permissions dropped so ptrace is denied.","solutions":["Verify the target thread still exists (check thread ID validity / process alive) before reading registers","Run on a FreeBSD version and CPU that support PT_GETXSTATE (XSAVE-capable CPU, FreeBSD with xstate support)","Check ptrace permission (kern.securelevel, procfs/ptrace scope) and that delve runs as the same user or root","If the errno shown is nil/empty, patch the wrapper to capture errno properly (e.g. via C.errno or runtime.SetFinalizer-free cgo errno handling) to diagnose"],"exampleFix":"// before\nret, err := C.ptrace(C.PT_GETXSTATE, C.pid_t(tid), C.caddr_t(unsafe.Pointer(&xsaveBuf[0])), C.int(len))\nif ret != 0 {\n\treturn nil, fmt.Errorf(\"failed to get xstate: %v\", err)\n}\n// after\nret, err := C.ptrace(C.PT_GETXSTATE, C.pid_t(tid), C.caddr_t(unsafe.Pointer(&xsaveBuf[0])), C.int(len))\nif ret != 0 {\n\tif err == nil {\n\t\treturn nil, fmt.Errorf(\"failed to get xstate (PT_GETXSTATE), tid=%d, ret=%d\", tid, ret)\n\t}\n\treturn nil, fmt.Errorf(\"failed to get xstate: %v\", err)\n}","handlingStrategy":"try-catch","validationCode":"// before reading registers\nif !isThreadAlive(dbp, tid) {\n\treturn fmt.Errorf(\"thread %d no longer exists; cannot read xstate\", tid)\n}\n// optionally probe support once:\n// _, err := ptraceGetXsave(tid) // cache whether PT_GETXSTATE works at attach time","typeGuard":"func regReadErr(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"failed to get xstate\")\n}","tryCatchPattern":"regs, err := thread.Registers()\nif regReadErr(err) {\n\t// fall back to GPR-only path or mark thread dead\n\treturn nil, err\n}","preventionTips":["Check thread/process liveness before every register read","Verify FreeBSD version and CPU XSAVE support at attach time and degrade gracefully","Run delve with sufficient privileges (same UID or root)","Cache the xstate buffer size from a successful PT_GETXSTATE probe"],"tags":["freebsd","ptrace","registers","xsave","cgo"],"backgroundTag":"ptrace-xstate-read-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}