Zubin pushed to branch wip/9.12.3-backports at Glasgow Haskell Compiler / GHC Commits: a632e54c by Teo Camarasu at 2025-08-20T18:08:32+05:30 rts: spin if we see a WHITEHOLE in messageBlackHole When a BLACKHOLE gets cancelled in raiseAsync, we indirect to a THUNK. GC can then shortcut this, replacing our BLACKHOLE with a fresh THUNK. This THUNK is not guaranteed to have a valid indirectee field. If at the same time, a message intended for the previous BLACKHOLE is processed and concurrently we BLACKHOLE the THUNK, thus temporarily turning it into a WHITEHOLE, we can get a segfault, since we look at the undefined indirectee field of the THUNK The fix is simple: spin if we see a WHITEHOLE, and it will soon be replaced with a valid BLACKHOLE. Resolves #26205 (cherry picked from commit 4021181ee0860aca2054883a531f3312361cc701) - - - - - ad7e4a6f by Teo Camarasu at 2025-08-20T18:09:07+05:30 rts: ensure MessageBlackHole.link is always a valid closure We turn a MessageBlackHole into an StgInd in wakeBlockingQueue(). Therefore it's important that the link field, which becomes the indirection field, always points to a valid closure. It's unclear whether it's currently possible for the previous behaviour to lead to a crash, but it's good to be consistent about this invariant nonetheless. Co-authored-by: Andreas Klebinger <klebinger.andreas@gmx.at> (cherry picked from commit a8b2fbae6bcf20bc2f3fe58803096d2a9c5fc43d) - - - - - 3 changed files: - rts/Messages.c - rts/StgMiscClosures.cmm - rts/Updates.h Changes: ===================================== rts/Messages.c ===================================== @@ -180,13 +180,22 @@ uint32_t messageBlackHole(Capability *cap, MessageBlackHole *msg) bh_info != &stg_CAF_BLACKHOLE_info && bh_info != &__stg_EAGER_BLACKHOLE_info && bh_info != &stg_WHITEHOLE_info) { - // if it is a WHITEHOLE, then a thread is in the process of - // trying to BLACKHOLE it. But we know that it was once a - // BLACKHOLE, so there is at least a valid pointer in the - // payload, so we can carry on. return 0; } + // If we see a WHITEHOLE then we should wait for it to turn into a BLACKHOLE. + // Otherwise we might look at the indirectee and segfault. + // See "Exception handling" in Note [Thunks, blackholes, and indirections] + // We might be looking at a *fresh* THUNK being WHITEHOLE-d so we can't + // guarantee that the indirectee is a valid pointer. +#if defined(THREADED_RTS) + if (bh_info == &stg_WHITEHOLE_info) { + while(ACQUIRE_LOAD(&bh->header.info) == &stg_WHITEHOLE_info) { + busy_wait_nop(); + } + } +#endif + // The blackhole must indirect to a TSO, a BLOCKING_QUEUE, an IND, // or a value. StgClosure *p; ===================================== rts/StgMiscClosures.cmm ===================================== @@ -31,6 +31,7 @@ import CLOSURE ENT_VIA_NODE_ctr; import CLOSURE RtsFlags; import CLOSURE stg_BLOCKING_QUEUE_CLEAN_info; import CLOSURE stg_BLOCKING_QUEUE_DIRTY_info; +import CLOSURE stg_END_TSO_QUEUE_closure; import CLOSURE stg_IND_info; import CLOSURE stg_MSG_BLACKHOLE_info; import CLOSURE stg_TSO_info; @@ -574,6 +575,9 @@ retry: MessageBlackHole_tso(msg) = CurrentTSO; MessageBlackHole_bh(msg) = node; + // Ensure that the link field is a valid closure, + // since we might turn this into an indirection in wakeBlockingQueue() + MessageBlackHole_link(msg) = stg_END_TSO_QUEUE_closure; SET_HDR(msg, stg_MSG_BLACKHOLE_info, CCS_SYSTEM); // messageBlackHole has appropriate memory barriers when this object is exposed. // See Note [Heap memory barriers]. ===================================== rts/Updates.h ===================================== @@ -333,6 +333,10 @@ * `AP_STACK` closure recording the aborted execution state. * See `RaiseAsync.c:raiseAsync` for details. * + * This can combine with indirection shortcutting during GC to replace a BLACKHOLE + * with a fresh THUNK. We should be very careful here since the THUNK will have an + * undefined value in the indirectee field. Looking at the indirectee field can then + * lead to a segfault such as #26205. * * CAFs * ---- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/09e66d31aff30073085e4ec06cbbf83... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/09e66d31aff30073085e4ec06cbbf83... You're receiving this email because of your account on gitlab.haskell.org.