Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
a8b2fbae
by Teo Camarasu at 2025-08-13T21:07:24-04:00
-
4021181e
by Teo Camarasu at 2025-08-13T21:07:24-04:00
3 changed files:
Changes:
... | ... | @@ -180,13 +180,22 @@ uint32_t messageBlackHole(Capability *cap, MessageBlackHole *msg) |
180 | 180 | bh_info != &stg_CAF_BLACKHOLE_info &&
|
181 | 181 | bh_info != &__stg_EAGER_BLACKHOLE_info &&
|
182 | 182 | bh_info != &stg_WHITEHOLE_info) {
|
183 | - // if it is a WHITEHOLE, then a thread is in the process of
|
|
184 | - // trying to BLACKHOLE it. But we know that it was once a
|
|
185 | - // BLACKHOLE, so there is at least a valid pointer in the
|
|
186 | - // payload, so we can carry on.
|
|
187 | 183 | return 0;
|
188 | 184 | }
|
189 | 185 | |
186 | + // If we see a WHITEHOLE then we should wait for it to turn into a BLACKHOLE.
|
|
187 | + // Otherwise we might look at the indirectee and segfault.
|
|
188 | + // See "Exception handling" in Note [Thunks, blackholes, and indirections]
|
|
189 | + // We might be looking at a *fresh* THUNK being WHITEHOLE-d so we can't
|
|
190 | + // guarantee that the indirectee is a valid pointer.
|
|
191 | +#if defined(THREADED_RTS)
|
|
192 | + if (bh_info == &stg_WHITEHOLE_info) {
|
|
193 | + while(ACQUIRE_LOAD(&bh->header.info) == &stg_WHITEHOLE_info) {
|
|
194 | + busy_wait_nop();
|
|
195 | + }
|
|
196 | + }
|
|
197 | +#endif
|
|
198 | + |
|
190 | 199 | // The blackhole must indirect to a TSO, a BLOCKING_QUEUE, an IND,
|
191 | 200 | // or a value.
|
192 | 201 | StgClosure *p;
|
... | ... | @@ -31,6 +31,7 @@ import CLOSURE ENT_VIA_NODE_ctr; |
31 | 31 | import CLOSURE RtsFlags;
|
32 | 32 | import CLOSURE stg_BLOCKING_QUEUE_CLEAN_info;
|
33 | 33 | import CLOSURE stg_BLOCKING_QUEUE_DIRTY_info;
|
34 | +import CLOSURE stg_END_TSO_QUEUE_closure;
|
|
34 | 35 | import CLOSURE stg_IND_info;
|
35 | 36 | import CLOSURE stg_MSG_BLACKHOLE_info;
|
36 | 37 | import CLOSURE stg_TSO_info;
|
... | ... | @@ -588,6 +589,9 @@ retry: |
588 | 589 | |
589 | 590 | MessageBlackHole_tso(msg) = CurrentTSO;
|
590 | 591 | MessageBlackHole_bh(msg) = node;
|
592 | + // Ensure that the link field is a valid closure,
|
|
593 | + // since we might turn this into an indirection in wakeBlockingQueue()
|
|
594 | + MessageBlackHole_link(msg) = stg_END_TSO_QUEUE_closure;
|
|
591 | 595 | SET_HDR(msg, stg_MSG_BLACKHOLE_info, CCS_SYSTEM);
|
592 | 596 | // messageBlackHole has appropriate memory barriers when this object is exposed.
|
593 | 597 | // See Note [Heap memory barriers].
|
... | ... | @@ -333,6 +333,10 @@ |
333 | 333 | * `AP_STACK` closure recording the aborted execution state.
|
334 | 334 | * See `RaiseAsync.c:raiseAsync` for details.
|
335 | 335 | *
|
336 | + * This can combine with indirection shortcutting during GC to replace a BLACKHOLE
|
|
337 | + * with a fresh THUNK. We should be very careful here since the THUNK will have an
|
|
338 | + * undefined value in the indirectee field. Looking at the indirectee field can then
|
|
339 | + * lead to a segfault such as #26205.
|
|
336 | 340 | *
|
337 | 341 | * CAFs
|
338 | 342 | * ----
|