#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