[GHC] #14346: 8.2.1 regression: heap corruption after safe foreign calls

GHC ghc-devs at haskell.org
Wed Oct 18 12:14:41 UTC 2017


#14346: 8.2.1 regression: heap corruption after safe foreign calls
-------------------------------------+-------------------------------------
        Reporter:  andrewchen        |                Owner:  (none)
            Type:  bug               |               Status:  infoneeded
        Priority:  highest           |            Milestone:
       Component:  Runtime System    |              Version:  8.2.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  Runtime crash     |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by alexbiehl):

 I had a look at the cmm code for comment [comment:14] and I have some
 questions:

 {{{
       c4CO: // global
           _s4Bx::I64 = R1 + 16; <---- assign _s4Bx the pointer to the
 first
                                       byte of the bytearray
                                       (16 byte = infotable ptr + length
 field )
           goto c4CW;
       c4CW: // global
           I32[_s4Bx::I64] = 3735928559 :: W32;
           (_s4BE::I64) = call "ccall" arg hints:  []  result hints:
 [`signed'] rtsSupportsBoundThreads();
           if (_s4BE::I64 != 0) goto c4Dz; else goto c4DE;
       c4Dz: // global
           I64[Sp - 8] = block_c4Dx_info;
           R2 = Main.main2_closure+1;
           I64[Sp] = _s4Bx::I64;   <------ is it ok to store an address
 which clearly points
                                           into heap allocated memory but
 doesn't point to
                                           an info table?

           Sp = Sp - 8;
           call GHC.Conc.Windows.threadDelay1_info(R2) returns to c4Dx,
 args: 8, res: 8, upd: 8;
       c4Dx: // global
           _s4Bx::I64 = I64[Sp + 8];
           goto c4D2;
       c4DE: // global
           I64[Sp - 8] = block_c4DD_info;
           R1 = 10;              <------- overwrite R1, R1 was our *only*
                                          reference to the bytearray
 closure.
           I64[Sp] = _s4Bx::I64;
           Sp = Sp - 8;
           call stg_delay#(R1) returns to c4DD, args: 8, res: 8, upd: 8;
       c4DD: // global
           _s4Bx::I64 = I64[Sp + 8];
           goto c4D2;
       c4D2: // global
 }}}

  - The only reference to the ByteArray closure is in R1
  - _s4Bx points to the first byte in the byte array
  - In block c4DE R1 is overwritten.
  - The rtsSupportsBoundThreads is a ccall, don't we have to save R1 over
 these calls?

 Maybe the garbage collector assumes the ByteArray is dead and collects it
 too early?

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


More information about the ghc-tickets mailing list