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

GHC ghc-devs at haskell.org
Fri Oct 13 14:18:45 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 bgamari):

 I could have sworn I left a comment last night but it seems I am mistaken.
 Here is what I discovered while looking into this so far:

 The test is indeed rather environment sensitive. Moreover, as it doesn't
 occur under `rr` I strongly suspect it's a race of some sort. When
 compiled with `-debug` the eventual segmentation fault always seems to
 occur in `stg_putMVarzh`. Specifically here,
 {{{
 Dump of assembler code for function stg_putMVarzh:
    0x00000000004ab1b0 <+0>:     cmpl   $0x1,0x4f4800
    0x00000000004ab1b8 <+8>:     je     0x4ab35e <stg_putMVarzh+430>
    0x00000000004ab1be <+14>:    mov    $0x479e18,%eax
    0x00000000004ab1c3 <+19>:    mov    %rbx,%rcx
    0x00000000004ab1c6 <+22>:    sub    $0x8,%rsp
    0x00000000004ab1ca <+26>:    mov    %rcx,%rdi
    0x00000000004ab1cd <+29>:    mov    %rax,%rcx
    0x00000000004ab1d0 <+32>:    xor    %eax,%eax
    0x00000000004ab1d2 <+34>:    callq  *%rcx
    0x00000000004ab1d4 <+36>:    add    $0x8,%rsp
    0x00000000004ab1d8 <+40>:    cmpq   $0x4f2c30,0x18(%rbx)
    0x00000000004ab1e0 <+48>:    jne    0x4ab366 <stg_putMVarzh+438>
    0x00000000004ab1e6 <+54>:    mov    0x8(%rbx),%rcx
    0x00000000004ab1ea <+58>:    cmp    $0x4f2c30,%rcx
    0x00000000004ab1f1 <+65>:    je     0x4ab466 <stg_putMVarzh+694>
    0x00000000004ab1f7 <+71>:    cmpq   $0x4ac2f0,(%rcx)
    0x00000000004ab1fe <+78>:    je     0x4ab45d <stg_putMVarzh+685>
    0x00000000004ab204 <+84>:    cmpq   $0x4aca20,(%rcx)
    0x00000000004ab20b <+91>:    je     0x4ab45d <stg_putMVarzh+685>
    0x00000000004ab211 <+97>:    mov    0x10(%rcx),%rdx
    0x00000000004ab215 <+101>:   mov    0x8(%rcx),%rsi
    0x00000000004ab219 <+105>:   mov    %rsi,0x8(%rbx)
    0x00000000004ab21d <+109>:   cmpq   $0x4f2c30,0x8(%rbx)
    0x00000000004ab225 <+117>:   jne    0x4ab22f <stg_putMVarzh+127>
    0x00000000004ab227 <+119>:   movq   $0x4f2c30,0x10(%rbx)
 => 0x00000000004ab22f <+127>:   cmp    0x28(%rdx),%rbx
    0x00000000004ab233 <+131>:   je     0x4ab276 <stg_putMVarzh+198>
    ...
 }}}
 I believe this corresponds to this bit of C--,
 {{{#!c
     ...

     tso = StgMVarTSOQueue_tso(q);
     StgMVar_head(mvar) = StgMVarTSOQueue_link(q);
     if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { // cmpq
 $0x4f2c30,0x8(%rbx)
         StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; // movq
 $0x4f2c30,0x10(%rbx)
     }

     ASSERT(StgTSO_block_info(tso) == mvar);             // cmp
 0x28(%rdx),%rbx

     ...
 }}}

 Indeed we find that,
 {{{
 >>> print/a $rbx
 $1 = 0x42000b8400
 >>> print/a $rdx
 $2 = 0x42deadbeef
 }}}
 Yikes!

 This sounds to me like we reentered STG while forgetting to do some bit of
 cleanup from the foreign call.

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


More information about the ghc-tickets mailing list