bpo-40887: Don't use finalized free lists (GH-20700)

In debug mode, ensure that free lists are no longer used after being
finalized. Set numfree to -1 in finalization functions
(eg. _PyList_Fini()), and then check that numfree is not equal to -1
before using a free list (e.g list_dealloc()).
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 0fe9f2a..0dad42e 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -595,6 +595,10 @@
     else {
         PyInterpreterState *interp = _PyInterpreterState_GET();
         struct _Py_frame_state *state = &interp->frame;
+#ifdef Py_DEBUG
+        // frame_dealloc() must not be called after _PyFrame_Fini()
+        assert(state->numfree != -1);
+#endif
         if (state->numfree < PyFrame_MAXFREELIST) {
             ++state->numfree;
             f->f_back = state->free_list;
@@ -790,6 +794,10 @@
         }
     }
     else {
+#ifdef Py_DEBUG
+        // frame_alloc() must not be called after _PyFrame_Fini()
+        assert(state->numfree != -1);
+#endif
         assert(state->numfree > 0);
         --state->numfree;
         f = state->free_list;
@@ -1188,6 +1196,10 @@
 _PyFrame_Fini(PyThreadState *tstate)
 {
     _PyFrame_ClearFreeList(tstate);
+#ifdef Py_DEBUG
+    struct _Py_frame_state *state = &tstate->interp->frame;
+    state->numfree = -1;
+#endif
 }
 
 /* Print summary info about the state of the optimized allocator */