Skip to content

POSIX fibers crash on macOS arm64: context pointer truncated through makecontext varargs #52

Description

@Kamayuq

Hey Schobi encountered an issue with Relacy on macOS.

This is what the agent found:

In relacy/platform.hpp, create_fiber passes the fiber_ctx_t* through a single makecontext argument (makecontext(&fib.fib, (void(*)())fiber_start_fnc, 1, &ctx)). POSIX specifies makecontext arguments as int, so on LP64 targets the pointer is truncated to 32 bits. On macOS arm64 this faults on the first fiber start: thread stacks live at 0x16F_xxxx_xxxx, so fiber_start_fnc receives the pointer with its top bits cut (e.g. 0x16fdfc3f0 → 0x6fdfc3f0) and crashes dereferencing it. Linux x86-64 escapes only by ABI accident (glibc passes the varargs in full 64-bit register slots).

Fix (two-line, the classic idiom): split the pointer into two unsigned halves at the makecontext call and reassemble in the trampoline — static void fiber_start_fnc(unsigned hi, unsigned lo) with (uintptr_t)hi << 32 | lo, called with 2, (unsigned)((uintptr_t)&ctx >> 32), (unsigned)(uintptr_t)&ctx. Verified: with this change (plus building the user TU with -D_XOPEN_SOURCE=700 -D_DARWIN_C_SOURCE, which macOS requires for the full ucontext_t layout — without it the SDK's 56-byte ucontext_t has no inline mcontext storage and getcontext writes ~880 bytes out of bounds), the full relacy suite runs green on an M4 Max.

Edit: And I could use a hug right now.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions