Skip to content

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.

Edited by Alexis King
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information