GH-96754: Check whether the interpreter frame is complete before creating frame object. (GH-96776)

diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-09-12-16-58-22.gh-issue-96754.0GRme5.rst b/Misc/NEWS.d/next/Core and Builtins/2022-09-12-16-58-22.gh-issue-96754.0GRme5.rst
new file mode 100644
index 0000000..beac84e
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-09-12-16-58-22.gh-issue-96754.0GRme5.rst
@@ -0,0 +1,3 @@
+Make sure that all frame objects created are created from valid interpreter
+frames. Prevents the possibility of invalid frames in backtraces and signal
+handlers.
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index e3b37f1..0f30b4d 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -1832,6 +1832,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
     _Py_atomic_store(&is_tripped, 0);
 
     _PyInterpreterFrame *frame = tstate->cframe->current_frame;
+    while (frame && _PyFrame_IsIncomplete(frame)) {
+        frame = frame->previous;
+    }
     signal_state_t *state = &signal_global_state;
     for (int i = 1; i < Py_NSIG; i++) {
         if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) {
diff --git a/Python/ceval.c b/Python/ceval.c
index 20d0e1c..091b0eb 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -5113,9 +5113,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
 #endif
 
         /* Log traceback info. */
-        PyFrameObject *f = _PyFrame_GetFrameObject(frame);
-        if (f != NULL) {
-            PyTraceBack_Here(f);
+        if (!_PyFrame_IsIncomplete(frame)) {
+            PyFrameObject *f = _PyFrame_GetFrameObject(frame);
+            if (f != NULL) {
+                PyTraceBack_Here(f);
+            }
         }
 
         if (tstate->c_tracefunc != NULL) {
diff --git a/Python/pystate.c b/Python/pystate.c
index a0d61d7..23e9d24 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1406,6 +1406,9 @@ _PyThread_CurrentFrames(void)
         PyThreadState *t;
         for (t = i->threads.head; t != NULL; t = t->next) {
             _PyInterpreterFrame *frame = t->cframe->current_frame;
+            while (frame && _PyFrame_IsIncomplete(frame)) {
+                frame = frame->previous;
+            }
             if (frame == NULL) {
                 continue;
             }