From 95e271b2266b8f2e7b60ede86ccf3ede4a7f83eb Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 6 Sep 2022 17:37:47 +0100 Subject: [PATCH] GH-96612: Skip incomplete frames in tracemalloc traces. (GH-96613) --- Lib/test/test_tracemalloc.py | 14 ++++++++++++++ .../2022-09-06-14-26-36.gh-issue-96612.P4ZbeY.rst | 1 + Modules/_tracemalloc.c | 11 ++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-09-06-14-26-36.gh-issue-96612.P4ZbeY.rst diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index d2a5ede61e3ff1..94bcee302fe730 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -360,6 +360,20 @@ def test_fork(self): else: support.wait_process(pid, exitcode=0) + def test_no_incomplete_frames(self): + tracemalloc.stop() + tracemalloc.start(8) + + def f(x): + def g(): + return x + return g + + obj = f(0).__closure__[0] + traceback = tracemalloc.get_object_traceback(obj) + self.assertIn("test_tracemalloc", traceback[-1].filename) + self.assertNotIn("test_tracemalloc", traceback[-2].filename) + class TestSnapshot(unittest.TestCase): maxDiff = 4000 diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-09-06-14-26-36.gh-issue-96612.P4ZbeY.rst b/Misc/NEWS.d/next/Core and Builtins/2022-09-06-14-26-36.gh-issue-96612.P4ZbeY.rst new file mode 100644 index 00000000000000..52e92703c9c483 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-09-06-14-26-36.gh-issue-96612.P4ZbeY.rst @@ -0,0 +1 @@ +Make sure that incomplete frames do not show up in tracemalloc traces. diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index ae09869deda704..44a1f7b673c0eb 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -400,7 +400,13 @@ traceback_get_frames(traceback_t *traceback) } _PyInterpreterFrame *pyframe = tstate->cframe->current_frame; - for (; pyframe != NULL;) { + for (;;) { + while (pyframe && _PyFrame_IsIncomplete(pyframe)) { + pyframe = pyframe->previous; + } + if (pyframe == NULL) { + break; + } if (traceback->nframe < _Py_tracemalloc_config.max_nframe) { tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]); assert(traceback->frames[traceback->nframe].filename != NULL); @@ -410,8 +416,7 @@ traceback_get_frames(traceback_t *traceback) traceback->total_nframe++; } - _PyInterpreterFrame *back = pyframe->previous; - pyframe = back; + pyframe = pyframe->previous; } }