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-glfwDLL, it will work correctly.) - There needs to be an
extern-declared variable. (For example, uncommenting the lines mentioning thefoovariable will make the issue go away.) - There needs to be at least two
.cfiles. 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 ofbarandbazin 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 |