[GHC] #11978: running a profiled build of shake test suite with rts args +RTS -hb -N10 triggers SIGSEGV

GHC ghc-devs at haskell.org
Tue May 3 06:22:37 UTC 2016


#11978: running a profiled build of shake test suite with rts args  +RTS -hb -N10
triggers SIGSEGV
---------------------------------+----------------------------------------
        Reporter:  carter        |                Owner:
            Type:  bug           |               Status:  patch
        Priority:  highest       |            Milestone:
       Component:  Compiler      |              Version:  8.0.1
      Resolution:                |             Keywords:
Operating System:  MacOS X       |         Architecture:  Unknown/Multiple
 Type of failure:  None/Unknown  |            Test Case:
      Blocked By:                |             Blocking:
 Related Tickets:  #4820         |  Differential Rev(s):  phab:D2159
       Wiki Page:                |
---------------------------------+----------------------------------------

Comment (by erikd):

 The whole issue arises because we enter the function `overwritingClosure`
 with a closure of type `WHITEHOLE` and that happens because
 `executeMessage` (in rts/Messages.c calls `doneWithMsgThrowTo`.

 So lets look at the interesting part of `executeMessage` with some extra
 comments explaining what I think is happening:

 {{{#!C
 void
 executeMessage (Capability *cap, Message *m)
 {
     const StgInfoTable *i;

 loop:
     write_barrier(); // allow m->header to be modified by another thread
     i = m->header.info;
     if (i == &stg_MSG_TRY_WAKEUP_info)
     {
         StgTSO *tso = ((MessageWakeup *)m)->tso;
         debugTraceCap(DEBUG_sched, cap, "message: try wakeup thread %ld",
                       (W_)tso->id);
         tryWakeupThread(cap, tso);
     }
     else if (i == &stg_MSG_THROWTO_info)
     {
         MessageThrowTo *t = (MessageThrowTo *)m;
         uint32_t r;
 //** This shadows the outer variable named `i`, but that seems ok.
         const StgInfoTable *i;

 //** lockClosure writes `&stg_WHITEHOLE_info` to `p->header.info` and
 returns
 //** the old value of `p->header.info`.
         i = lockClosure((StgClosure*)m);

 //** t->header.info == &stg_WHITEHOLE_info

         if (i != &stg_MSG_THROWTO_info) {
             unlockClosure((StgClosure*)m, i);
             goto loop;
         }

         debugTraceCap(DEBUG_sched, cap, "message: throwTo %ld -> %ld",
                       (W_)t->source->id, (W_)t->target->id);

         ASSERT(t->source->why_blocked == BlockedOnMsgThrowTo);
         ASSERT(t->source->block_info.closure == (StgClosure *)m);

         r = throwToMsg(cap, t);

 //** t->header.info == &stg_WHITEHOLE_info

         switch (r) {
         case THROWTO_SUCCESS: {
             // this message is done
             StgTSO *source = t->source;

 //** doneWithMsgThrowTo calls overwritingClosure with
 //** t->header.info == &stg_WHITEHOLE_info

             doneWithMsgThrowTo(t);
             tryWakeupThread(cap, source);
             break;
         }
 }}}

 @simonmar, on IRC you said that in `overwritingClosure` the closure type
 should not be `WHITEHOLE`, but the above code suggests that it can be. If
 the `t->header.info` value is supposed to be changed back to
 `&stg_MSG_THROWTO_info` (or something else), where is that supposed to
 happen?

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11978#comment:15>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list