[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