Skip to content

rts: Fix handling of global_link sanity checking

Ben Gamari requested to merge wip/T19146 into master

TSOs are a bit odd in that they have a global_link pointer field which is not scavenged by the GC. This field is used to track the generations[].[old]threads lists and is ultimately updated by MarkWeak.c:tidyThreadList.

Typically the fact that this field is not scavenged is fine as all reachable TSOs on the heap are guaranteed to be on some generation's thread list and therefore will be scavenged by tidyThreadList. However, the sanity checker poses a bit of a challenge here as it walks heap blocks directly and therefore may encounter TSOs which aren't reachable via the heap. For this reason, checkTSO does not check global_link. Instead, we only do so in checkGlobalTSOList, which by definition will only look at threads which are reachable via a thread list (and therefore must have won the forwarding-pointer race).

This also includes a number of other things that I stumbled across while fixing this:

  • Augment the LOOKS_LIKE_*_PTR utilities to catch pointers cleared by +RTS -DZ.
  • Ensure that +RTS -l -D... emits debugging output to the eventlog, as the documentation suggests that it should
  • Flush the eventlog with flushAllCapsEventsBufs on in the default internal error hook to ensure that we don't deadlock when we barf during GC
  • Add a utility function, printGlobalThreads, which prints all generations' threads and old_threads lists

Fixes #19146 (closed).

Edited by Ben Gamari

Merge request reports