[GHC] #12031: GHCi segfaults on Windows when compiling C code using extern-declared variable

GHC ghc-devs at haskell.org
Sat May 7 16:21:02 UTC 2016


#12031: GHCi segfaults on Windows when compiling C code using extern-declared
variable
----------------------------------------+-------------------------------
           Reporter:  RyanGlScott       |             Owner:
               Type:  bug               |            Status:  new
           Priority:  normal            |         Milestone:
          Component:  GHCi              |           Version:  8.0.1
           Keywords:                    |  Operating System:  Windows
       Architecture:  Unknown/Multiple  |   Type of failure:  GHCi crash
          Test Case:                    |        Blocked By:
           Blocking:                    |   Related Tickets:
Differential Rev(s):                    |         Wiki Page:
----------------------------------------+-------------------------------
 Phyx- and I [https://phabricator.haskell.org/D1805#59850 noticed] that
 `bindings-GLFW` unpredictably segfaults when running this simple program
 in interpreted code:

 {{{#!hs
 module Main where

 import qualified Graphics.UI.GLFW as G

 main :: IO ()
 main = do
   successfulInit <- G.init
   return ()
 }}}

 Phyx- [https://phabricator.haskell.org/D1805#60275 suspected] that it had
 something to do with the `extern`-declared variables used in the GLFW
 library itself. To avoid requiring a dependency on GLFW, I boiled the
 issue down to a small, reproducible example with no dependencies, located
 at https://github.com/RyanGlScott/extern-bug. I will reproduce the code
 below:

 {{{#!c
 // foo.h
 #ifndef FOO_H
 #define FOO_H

 extern int foo;

 void bar(void);
 void baz(void);

 #endif
 }}}

 {{{#!c
 // bar.c
 #include "foo.h"

 int foo = 0;

 void bar(void) {
     foo = 1;

     baz();
 }
 }}}

 {{{#!c
 // baz.c
 #include "foo.h"
 #include <stdio.h>

 void baz(void) {
     printf("The value of foo is %d\n", foo); // Segfaults on this line
     fflush(stdout);
 }
 }}}

 {{{#!hs

 -- ExternBug.hs
 {-# LANGUAGE ForeignFunctionInterface #-}
 module ExternBug (bar) where

 {-# INCLUDE foo.h #-}

 foreign import ccall "bar"
   bar :: IO ()
 }}}

 While I've managed to reproduce this bug sporadically with GHC 7.10.3, it
 happens far more reliably with GHC 8.0. Here is what I did to trigger the
 segfault:

 1. Run `ghc bar.c baz.c ExternBug.hs`
 2. Run `ghci bar.o baz.o ExternBug.hs`
 3. Invoke `bar`

 I'm not sure what's happening, but there seem to be four important
 ingredients here:

 1. This needs to be run in interpreted code. Compiled code does not have
 this issue.
 2. The C sources need to be compiled to object code using GHC. (For
 example, if you link the MSYS2-provided `mingw-w64-x86_64-glfw` DLL, it
 will work correctly.)
 3. There needs to be an `extern`-declared variable. (For example,
 uncommenting the lines mentioning the `foo` variable will make the issue
 go away.)
 4. There needs to be at least two `.c` files. One file needs to assign a
 value to the `extern`-declared variable, and the other file needs to use
 the value. (For example, if you put the definitions of `bar` and `baz` in
 the same file, the bug doesn't occur.)

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


More information about the ghc-tickets mailing list