Segfault in GHCi with a profiled compiler when loading code linked into a static library
I have discovered a minimal program that causes GHCi to segfault when GHC itself has been compiled with profiling (more specifically, using the perf+profiled_ghc+no_dynamic_ghc
flavour). Here is the code:
module A where
foo :: () -> ()
foo = {-# SCC "foo/expr" #-} (\x -> x)
{-# SCC foo #-}
module B where
import A
bar :: ()
bar = foo ()
Unfortunately, I’ve only managed to trigger the segfault if the code is loaded as a .a
archive, which requires a little setup, since the archive must be registered as a package. This package configuration will suffice:
name: example
version: 0.0.0
visibility: public
id: example
key: example
abi: inplace
exposed: True
exposed-modules: A B
import-dirs: build
library-dirs: build
library-dirs-static: build
dynamic-library-dirs: build
hs-libraries: HSexample
depends: base-4.18.0.0-inplace
Then we can run the following commands to build the package and trigger the segfault:
$ ghc --make -i -isrc A B -prof -osuf p_o -hisuf p_hi -outputdir build -this-unit-id example
[1 of 2] Compiling A ( src/A.hs, build/A.p_o )
[2 of 2] Compiling B ( src/B.hs, build/B.p_o )
$ ar -r build/libHSexample_p.a build/A.p_o build/B.p_o
ar: creating build/libHSexample_p.a
$ ghc-pkg recache --package-db package.db
$ ghc --interactive -package-db package.db -package-id example
GHCi, version 9.7.20230512: https://www.haskell.org/ghc/ :? for help
ghci> import B
ghci> bar
fish: Job 1, '/home/alexis/code/haskell/ghc/m…' terminated by signal SIGSEGV (Address boundary error)
This seems likely to be a bug in the RTS linker, since the issue goes away if code is loaded from the .p_o
files directly.
To make it easier for other people to reproduce this issue, I’ve created an archive containing everything necessary to trigger the problem: standalone.zip Extract the archive, enter the root directory, and run the following command:
env GHC=path/to/your/profiled/ghc ./build.sh
This should reliably trigger the segfault on GHC HEAD when compiled with the perf+profiled_ghc+no_dynamic_ghc
.