GHCi segfaults on Windows when compiling C code using extern-declared variable
Phyx- and I noticed that bindings-GLFW
unpredictably segfaults when running this simple program in interpreted code:
module Main where
import qualified Graphics.UI.GLFW as G
main :: IO ()
main = do
successfulInit <- G.init
return ()
Phyx- 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:
// foo.h
#ifndef FOO_H
#define FOO_H
extern int foo;
void bar(void);
void baz(void);
#endif
// bar.c
#include "foo.h"
int foo = 0;
void bar(void) {
foo = 1;
baz();
}
// 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);
}
-- 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:
- Run
ghc bar.c baz.c ExternBug.hs
- Run
ghci bar.o baz.o ExternBug.hs
- Invoke
bar
I'm not sure what's happening, but there seem to be four important ingredients here:
- This needs to be run in interpreted code. Compiled code does not have this issue.
- 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.) - There needs to be an
extern
-declared variable. (For example, uncommenting the lines mentioning thefoo
variable will make the issue go away.) - There needs to be at least two
.c
files. One file needs to assign a value to theextern
-declared variable, and the other file needs to use the value. (For example, if you put the definitions ofbar
andbaz
in the same file, the bug doesn't occur.)
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | GHCi |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | Phyx- |
Operating system | |
Architecture | Unknown/Multiple |