#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