Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

3 changed files:

Changes:

  • rts/Messages.c
    ... ... @@ -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;
    

  • rts/StgMiscClosures.cmm
    ... ... @@ -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].
    

  • rts/Updates.h
    ... ... @@ -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
      * ----