[GHC] #8834: 64-bit windows cabal.exe segfaults in GC

GHC ghc-devs at haskell.org
Mon Mar 17 14:47:27 UTC 2014


#8834: 64-bit windows cabal.exe segfaults in GC
----------------------------------+----------------------------------
        Reporter:  awson          |            Owner:  jstolarek
            Type:  bug            |           Status:  patch
        Priority:  highest        |        Milestone:  7.8.1
       Component:  Compiler       |          Version:  7.8.1-rc2
      Resolution:                 |         Keywords:
Operating System:  Windows        |     Architecture:  x86_64 (amd64)
 Type of failure:  Runtime crash  |       Difficulty:  Unknown
       Test Case:                 |       Blocked By:
        Blocking:                 |  Related Tickets:
----------------------------------+----------------------------------

Comment (by jstolarek):

 Replying to [comment:56 simonpj]:
 >  * Can you (by experiment) find which of registers is causing the
 problem?  You fixed it by making them ''all'' caller saves, but that might
 be more than what's needed.
 >
 >  * You hypothesise that the C procedure `memchr` is destroying a callee-
 saves register.  Might it be possible to test this hypothesis directly?

 I looked at the implementation of `memchr` in `glibc` and it looks that on
 64 bits it is touching `%rsi` and `%rdi` registers (our R3 and R4,
 respectively). I changed this definition in
 [[GhcFile(includes/stg/MachRegs.h)]]:

 {{{
 #if !defined(mingw32_HOST_OS)
 #define CALLER_SAVES_R3
 #define CALLER_SAVES_R4
 #endif
 }}}

 to:

 {{{
 #define CALLER_SAVES_R3
 #define CALLER_SAVES_R4
 }}}

 (ie. I removed the conditional) and the segfault has disappeared. Looking
 at the Cmm confirms that R3 are R4 are now not sunk past the call to
 `memchr`:

 {{{
 c2hy:
     _s2dH::I64 = R5;
     _s2dG::I64 = R4;
     _s2dF::P64 = R3;
     _s2dK::I64 = R2 + R4;
     _c2fR::I64 = R5;
     (_s2dP::I64) = call "ccall" arg hints:  [PtrHint,
                                              `signed',]  result hints:
 [PtrHint] memchr(_s2dK::I64, 10, _c2fR::I64);
     if (_s2dP::I64 == 0) goto c2ht; else goto c2hu;
 c2ht:
     call MO_Touch(_s2dF::P64);
     I64[Hp - 128] = Data.ByteString.Internal.PS_con_info;
     P64[Hp - 120] = _s2dF::P64;
     I64[Hp - 112] = R2;
     I64[Hp - 104] = _s2dG::I64;
     I64[Hp - 96] = _s2dH::I64;
     I64[Hp - 88] = :_con_info;
     P64[Hp - 80] = Hp - 127;
     P64[Hp - 72] = GHC.Types.[]_closure+1;
     _c2ho::P64 = Hp - 86;
     Hp = Hp - 72;
     R1 = _c2ho::P64;
 }}}

 But one thing is not right here:

 {{{
 #if !defined(mingw32_HOST_OS)
 #define CALLER_SAVES_R3
 #define CALLER_SAVES_R4
 #endif
 }}}

 Under 64 bit Windows `mingw32_HOST_OS` should not be declared and
 therefore R3 and R4 should be defined as caller saves! As a quick sanity
 check I wrote this small C program and compiled it with the in-tree mingw
 gcc:

 {{{
 #include <stdio.h>
 #if !defined(mingw32_HOST_OS)
 int x = 1;
 #else
 int x = 2;
 #endif

 int main() {
 printf("%d",x);
 }
 }}}

 This program prints `1` as expected. Does anyone have any idea what might
 be going on here?

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


More information about the ghc-tickets mailing list