Don't call DEAD_WEAK finalizer again on shutdown (#7170)

Authored by simonmar.


Don't call DEAD_WEAK finalizer again on shutdown (Trac #7170)

There's a race condition like this:

  1. A foreign pointer gets promoted to the last generation
  2. It has its finalizer called manually
  3. We start shutting down the runtime in hs_exit_ from the main thread
  4. A minor GC starts running (scheduleDoGC) on one of the threads
  5. The minor GC notices that we're in SCHED_INTERRUPTING state and advances to SCHED_SHUTTING_DOWN
  6. The main thread tries to do major GC (with scheduleDoGC), but it exits early because we're in SCHED_SHUTTING_DOWN state
  7. We end up with a DEAD_WEAK left on the list of weak pointers of the last generation, because it relied on major GC removing it from that list

This change:

  • Ignores DEAD_WEAK finalizers when shutting down
  • Makes the major GC on shutdown more likely
  • Fixes a bogus assert

Test Plan:
before this diff
reproduced and after it doesn't

Reviewers: ezyang, austin, simonmar

Reviewed By: simonmar

Subscribers: bgamari, thomie

Differential Revision:

GHC Trac Issues: Trac #7170