Skip to content

v0.6.0 — errno Always-Capture (Breaking)

Latest

Choose a tag to compare

@kolkov kolkov released this 12 Jul 04:21
895a3fa

What's Changed

BREAKING: CallFunction now returns (syscall.Errno, error)

errno is always captured inside the assembly trampoline, immediately after the C function returns — the only thread-safe window before the Go runtime can migrate the goroutine to a different OS thread.

goffi is the first pure-Go FFI with correct errno capture on Linux.

Migration

// Before (v0.5.x):
err := ffi.CallFunction(cif, fn, &result, args)

// After (v0.6.0):
errno, err := ffi.CallFunction(cif, fn, &result, args)
// Or if errno not needed:
_, err := ffi.CallFunction(cif, fn, &result, args)

Why Always-Capture?

Opt-in CallFunctionErrno is a pit of failure — you don't know you need errno until the function fails, and by then the goroutine may be on a different OS thread. Cost: ~3-5 ns per call.

Platform Support

Platform errno function Library
Linux (glibc/musl) __errno_location libc.so.6
macOS __error libSystem.B.dylib
FreeBSD __error libc.so.7
Windows Returns errno=0 (uses GetLastError separately)

Also Includes (from v0.5.6 → v0.6.0)

  • Callback stack-move corruption fix (PR #59 by @tie)
  • sync.Pool for syscallArgs (goroutine stack safety)
  • structs.HostLayout on all ABI-boundary structs
  • Example avalue fix + CI examples check
  • FreeBSD ARM64 support (8 platforms total)

Thanks to @tie for the stack-move fix, @unxed for performance proposals, and @lkmavi for testing!