nonmovingTidyWeaks segfaults if w->key is static data
Summary
nonmovingTidyWeaks
has the following line:
https://gitlab.haskell.org/ghc/ghc/-/blob/d3a050d2a1eac0244f989badb3a2c75c84e0a160/rts/sm/NonMovingMark.c?page=3#L2014
bool key_in_nonmoving = Bdescr((StgPtr) w->key)->flags & BF_NONMOVING;
Here we check if the block descriptor of the key puts it in the nonmoving heap.
But if w->key
is static data and lives in the executables .data section, we may get a segfault trying to look up the Bdescr
.
I saw segfaults when testing my WIP branch for #24150 using the nonmoving_thr
way when running the GcStaticPointers test. I checked and it also happens with master
but not with my boot compiler which is ghc-9.6.2
.
Steps to reproduce
Run the GcStaticPointers
in the nonmoving_thr
way.
I am using the release+debug_info
flavour but I'm not sure if that's relevant.
It will segfault with this backtrace:
Thread 7 "nonmoving-mark" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffdffff6c0 (LWP 2028996)]
0x00000000004996ac in nonmovingTidyWeaks (queue=queue@entry=0x7fffb8000bc0) at rts/sm/NonMovingMark.c:2015
2015 if (!key_in_nonmoving || nonmovingIsNowAlive(w->key)) {
(gdb) bt
#0 0x00000000004996ac in nonmovingTidyWeaks (queue=queue@entry=0x7fffb8000bc0) at rts/sm/NonMovingMark.c:2015
#1 0x0000000000495cb5 in nonmovingMarkThreadsWeaks (mark_queue=0x7fffb8000bc0, budget=0x7fffdfffee70) at rts/sm/NonMoving.c:870
#2 nonmovingMark_ (mark_queue=mark_queue@entry=0x7fffb8000bc0, dead_weaks=dead_weaks@entry=0x7fffdfffeeb8, resurrected_threads=resurrected_threads@entry=0x7fffdfffeec0,
concurrent=concurrent@entry=true) at rts/sm/NonMoving.c:1077
#3 0x000000000049607d in nonmovingConcurrentMarkWorker (data=<optimized out>) at rts/sm/NonMoving.c:933
#4 nonmovingConcurrentMarkWorker (data=<optimized out>) at rts/sm/NonMoving.c:910
#5 0x00007ffff7cdee64 in start_thread () from /nix/store/9v5d40jyvmwgnq1nj8f19ji2rcc5dksd-glibc-2.37-45/lib/libc.so.6
#6 0x00007ffff7d609f0 in clone3 () from /nix/store/9v5d40jyvmwgnq1nj8f19ji2rcc5dksd-glibc-2.37-45/lib/libc.so.6
(gdb) p *w
$1 = {header = {info = 0x4a9810 <stg_WEAK_info>}, cfinalizers = 0x5101c8, key = 0x502570, value = 0x502570, finalizer = 0x502620, link = 0x4201868408}
(gdb) p Bdescr(w->key)
800
52688 18624 39240$2 = (bdescr *) 0x500080
And note that the address lies in the .data section of the executable.
Expected behavior
Not segfault.
Environment
- GHC version used: 9.9.20240221