[Git][ghc/ghc][master] rts: Fix segfault when using non-moving GC with profiling

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Wed Sep 25 21:11:39 UTC 2024



Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC


Commits:
ad0731ad by Zubin Duggal at 2024-09-25T17:10:18-04:00
rts: Fix segfault when using non-moving GC with profiling

`nonMovingCollect()` swaps out the `static_flag` value used as a
sentinel for `gct->scavenged_static_objects`, but the subsequent call
`resetStaticObjectForProfiling()` sees the old value of `static_flag` used as
the sentinel and segfaults. So we must call `resetStaticObjectForProfiling()`
before calling `nonMovingCollect()` as otherwise it looks for the incorrect
sentinel value

Fixes #25232 and #23958

Also teach the testsuite driver about nonmoving profiling ways
and stop disabling metric collection when nonmoving GC is enabled.

- - - - -


5 changed files:

- rts/sm/GC.c
- testsuite/config/ghc
- testsuite/driver/testlib.py
- + testsuite/tests/rts/T25232.hs
- testsuite/tests/rts/all.T


Changes:

=====================================
rts/sm/GC.c
=====================================
@@ -854,6 +854,18 @@ GarbageCollect (struct GcConfig config,
       }
   }
 
+#if defined(PROFILING)
+  // resetStaticObjectForProfiling() must be called before
+  // zeroing below.
+  // It must also be called before nonMovingCollect() as that
+  // swaps out the value of static_flag used as a sentinel
+  // in gct->scavenged_static_objects
+  // Not doing this lead to #25232 and #23958
+
+  // ToDo: fix the gct->scavenged_static_objects below
+  resetStaticObjectForProfiling(&g_retainerTraverseState, gct->scavenged_static_objects);
+#endif
+
   // Mark and sweep the oldest generation.
   // N.B. This can only happen after we've moved
   // oldest_gen->scavenged_large_objects back to oldest_gen->large_objects.
@@ -946,14 +958,6 @@ GarbageCollect (struct GcConfig config,
       checkUnload();
   }
 
-#if defined(PROFILING)
-  // resetStaticObjectForProfiling() must be called before
-  // zeroing below.
-
-  // ToDo: fix the gct->scavenged_static_objects below
-  resetStaticObjectForProfiling(&g_retainerTraverseState, gct->scavenged_static_objects);
-#endif
-
   // Start any pending finalizers.  Must be after
   // updateStableTables() and stableUnlock() (see #4221).
   RELEASE_SM_LOCK;


=====================================
testsuite/config/ghc
=====================================
@@ -125,6 +125,8 @@ config.way_flags = {
     'ext-interp'   : ['-fexternal-interpreter'],
     'nonmoving'    : [],
     'nonmoving_thr': ['-threaded'],
+    'nonmoving_prof': ['-prof'],
+    'nonmoving_thr_prof': ['-prof', '-threaded'],
     'nonmoving_thr_sanity': ['-threaded', '-debug'],
     'nonmoving_thr_ghc': ['+RTS', '-xn', '-N2', '-RTS', '-threaded'],
     'compacting_gc': [],


=====================================
testsuite/driver/testlib.py
=====================================
@@ -848,15 +848,12 @@ def _collect_stats(name: TestName, opts, metrics, deviation: Optional[int],
     if config.compiler_debugged and is_compiler_stats_test:
         opts.skip = True
 
-    # If there are any residency testing metrics then turn on RESIDENCY_OPTS and
-    # omit nonmoving GC ways, which don't support profiling.
+    # If there are any residency testing metrics then turn on RESIDENCY_OPTS
     if residency_testing_metrics() & metrics:
         if is_compiler_stats_test:
             _extra_hc_opts(name, opts, RESIDENCY_OPTS)
         else:
             _extra_run_opts(name, opts, RESIDENCY_OPTS)
-        # The nonmoving collector does not support -G1
-        _omit_ways(name, opts, [WayName(name) for name in ['nonmoving', 'nonmoving_thr', 'nonmoving_thr_ghc']])
 
     # How to read the result of the performance test
     def read_stats_file(way, metric_name):
@@ -1026,6 +1023,9 @@ def have_dynamic_prof( ) -> bool:
 def have_profiling( ) -> bool:
     return config.have_profiling
 
+def have_threaded( ) -> bool:
+    return config.ghc_with_threaded_rts
+
 def in_tree_compiler( ) -> bool:
     return config.in_tree_compiler
 


=====================================
testsuite/tests/rts/T25232.hs
=====================================
@@ -0,0 +1,14 @@
+module Main where
+
+import Control.Monad
+import Control.Monad.Trans.State.Strict
+import Data.IORef
+
+main :: IO ()
+main = do
+  ref <- newIORef ()
+  replicateM_ 1000 $ withIORef ref $ runStateT (pure ())
+
+withIORef :: IORef a -> (a -> IO (b, a)) -> IO b
+withIORef ref f =
+  readIORef ref >>= f >>= \(b, a) -> writeIORef ref a >> pure b


=====================================
testsuite/tests/rts/all.T
=====================================
@@ -616,3 +616,5 @@ test('IOManager', [js_skip, when(arch('wasm32'), skip), when(opsys('mingw32'), s
                   compile_and_run, [''])
 
 test('T24142', [req_target_smp], compile_and_run, ['-threaded -with-rtsopts "-N2"'])
+
+test('T25232', [unless(have_profiling(), skip), only_ways(['normal','nonmoving','nonmoving_prof','nonmoving_thr_prof']), extra_ways(['nonmoving', 'nonmoving_prof'] + (['nonmoving_thr_prof'] if have_threaded() else []))], compile_and_run, [''])



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ad0731ada00982ae66e0b5bb88ca7b97ece1313f

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ad0731ada00982ae66e0b5bb88ca7b97ece1313f
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240925/9f1c7a6a/attachment-0001.html>


More information about the ghc-commits mailing list