rts: Fix handling of global_link sanity checking
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 webarf
during GC - Add a utility function,
printGlobalThreads
, which prints all generations'threads
andold_threads
lists
Fixes #19146 (closed).