go-delve/delve · error
failed to set xstate
Error message
failed to set xstate: %v
What it means
ptraceSetXsave writes the thread's extended XSAVE state back with PT_SETXSTATE on FreeBSD/amd64. A non-zero return from ptrace is wrapped in this error. It means the kernel refused the xstate write (invalid buffer length, unsupported features in the buffer, or dead thread).
Solutions
- Confirm the target thread is alive before calling SetRegs-style register writes
- Ensure the xsave buffer length matches the CPU's xstate size (query once via PT_GETXSTATE and reuse that length)
- Upgrade/verify the FreeBSD kernel supports PT_SETXSTATE for the running CPU
- Capture errno properly if the formatted error is empty to identify the true cause
Example fix
// before
if regset.Xsave != nil {
return ptraceSetXsave(id, regset.Xsave)
}
// after
if regset.Xsave != nil {
if err := ptraceSetXsave(id, regset.Xsave); err != nil {
return fmt.Errorf("setxstate tid=%d: %w", id, err)
}
} Defensive patterns
Strategy: validation
Validate before calling
// before writing xstate
if !isThreadAlive(dbp, id) {
return fmt.Errorf("thread %d gone; skipping xstate write", id)
}
if len(xsaveBuf) != knownXstateSize {
return fmt.Errorf("xstate buffer %d != expected %d", len(xsaveBuf), knownXstateSize)
} Type guard
func isXstateWriteErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to set xstate")
} Prevention
- Re-read the xstate (PT_GETXSTATE) immediately before modifying so buffer size/features match the CPU
- Write registers only while the thread is stopped and alive
- Test xstate write support once at attach; disable FP register editing if unsupported
When it happens
Trigger: ptraceSetRegset -> ptraceSetXsave when the xsave buffer size does not match what the kernel expects for the CPU's enabled xstate features, the tid has exited, or PT_SETXSTATE is unsupported by the running kernel.
Common situations: Setting registers after the debuggee thread died; kernel/CPU with different XSAVE feature set than the buffer captured earlier (e.g. after exec of a new binary); running in restricted environments (jails/VMs) lacking xstate write support.
Related errors
- failed to get xstate
- failed to get xstate info
- failed to get FP registers
- failed to set FP registers
- can not set
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/ff229e66bb51684b.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/proc/native/ptrace_freebsd_amd64.go:62
// ptraceGetXsave gets the X86 XSAVE data for the given tid.
func ptraceGetXsave(tid int) ([]byte, error) {
len, err := ptraceXsaveLen(tid)
if err != nil {
return nil, err
}
xsaveBuf := make([]byte, len)
ret, err := C.ptrace(C.PT_GETXSTATE, C.pid_t(tid), C.caddr_t(unsafe.Pointer(&xsaveBuf[0])), C.int(len))
if ret != 0 {
return nil, fmt.Errorf("failed to get xstate: %v", err)
}
return xsaveBuf, nil
}
// ptraceSetXsave sets the X86 XSAVE data for the given tid.
func ptraceSetXsave(tid int, xsaveBuf []byte) error {
ret, err := C.ptrace(C.PT_SETXSTATE, C.pid_t(tid), C.caddr_t(unsafe.Pointer(&xsaveBuf[0])), C.int(len(xsaveBuf)))
if ret != 0 {
return fmt.Errorf("failed to set xstate: %v", err)
}
return nil
}
func ptraceGetRegset(id int) (*amd64util.AMD64Xstate, error) {
var regset amd64util.AMD64Xstate
ret, err := C.ptrace(C.PT_GETFPREGS, C.pid_t(id), C.caddr_t(unsafe.Pointer(®set.AMD64PtraceFpRegs)), C.int(0))
if ret != 0 {
return nil, fmt.Errorf("failed to get FP registers: %v", err)
}
regset.Xsave, err = ptraceGetXsave(id)
if err != nil {
return nil, err
}
err = amd64util.AMD64XstateRead(regset.Xsave, false, ®set, cpuid.AMD64XstateZMMHi256Offset())
return ®set, err
}
View on GitHub (pinned to a23773e6c3)