Ok, looking at 4030, which is this simple program:

main = do tid <- block $ forkIO $ let x = x in x
          killThread tid

It segfaults in stg_BLACKHOLE_info when attempting to
dereference... something (I haven't quite figured out
what yet; what's usually stored in 0x4(%esi) on 32-bit x86
when entering _info blocks?)

    0x822a6e0 <stg_CAF_BLACKHOLE_info>:  jmp    0x822a620 <stg_BLACKHOLE_info>
    0x822a620 <stg_BLACKHOLE_info>:      mov    0x4(%esi),%eax
    0x822a623 <stg_BLACKHOLE_info+3>:    test   $0x3,%eax
    0x822a628 <stg_BLACKHOLE_info+8>:    jne    0x822a663 
<stg_BLACKHOLE_info+67>
    0x822a62a <stg_BLACKHOLE_info+10>:   mov    (%eax),%ecx -- SEGFAULT!

Registers right at the segfault:

    eax            0x0      0
    ecx            0x28     40
    edx            0xb7a7e008       -1213734904
    ebx            0x8289acc        136878796
    esp            0xbfffcd98       0xbfffcd98
    ebp            0xb7a808f8       0xb7a808f8
    esi            0xb7a7f108       -1213730552
    edi            0xb7a7f10c       -1213730548
    eip            0x822a62a        0x822a62a <stg_BLACKHOLE_info+10>

I believe this is because the code generator didn't write
out the value to the heap, as seen comparing the correct and incorrect
C-- (irrelevant stack/heap overflow checks elided):

Correct:

        Hp = Hp + 8;
        if (Hp > I32[BaseReg + 92]) goto coY;
        I32[Hp - 4] = stg_CAF_BLACKHOLE_info;
        I32[Hp + 0] = I32[BaseReg + 96];
        foreign "ccall"
          newCAF((BaseReg, PtrHint), (R1, PtrHint))[_unsafe_call_];
        I32[R1 + 4] = Hp - 4;
        I32[R1] = stg_IND_STATIC_info;
        I32[Sp - 8] = stg_bh_upd_frame_info;
        I32[Sp - 4] = Hp - 4;

Incorrect:

        _r7::I32 = R1;
        Sp = Sp + 4;
        Hp = Hp + 8;
        // outOfLine should follow:
        // allocDynClosure
        I32[Hp - 4] = stg_CAF_BLACKHOLE_info;
        _cpa::I32 = Hp - 4;
        // XXX: I32[Hp + 0] is never written!!
        I32[Sp - 16] = _cpa::I32;
        foreign "ccall"
          newCAF((BaseReg, PtrHint), (R1, PtrHint))[_unsafe_call_];
        _cpa::I32 = I32[Sp - 16];
        I32[R1 + 4] = _cpa::I32;
        I32[R1] = stg_IND_STATIC_info;
        _cpa::I32 = I32[Sp - 16]; // Hp - 4
        I32[Sp - 8] = _cpa::I32;
        I32[Sp - 12] = stg_upd_frame_info;

It's not clear to me where in the code generator to look to fix this though.
Any pointers?

Cheers,
Edward

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to