https://github.com/python/cpython/commit/c17d30bf3408b0fde7344393e86bbd134e40bdd2
commit: c17d30bf3408b0fde7344393e86bbd134e40bdd2
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: gaogaotiantian <[email protected]>
date: 2025-01-25T15:12:19-05:00
summary:

[3.12] gh-58956: Set f_trace on frames with breakpoints after setting a new 
breakpoint (GH-124454) (#125549)

* gh-58956: Set f_trace on frames with breakpoints after setting a new 
breakpoint (GH-124454)
(cherry picked from commit 12eaadc0ad33411bb02945d700b6ed7e758bb188)

Co-authored-by: Tian Gao <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst
M Lib/bdb.py
M Lib/test/test_pdb.py

diff --git a/Lib/bdb.py b/Lib/bdb.py
index 8b63d9eca6da5f..085c17ce05d2fd 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -34,6 +34,7 @@ def __init__(self, skip=None):
         self.breaks = {}
         self.fncache = {}
         self.frame_returning = None
+        self.enterframe = None
 
         self._load_breaks()
 
@@ -341,6 +342,7 @@ def set_trace(self, frame=None):
 
         If frame is not specified, debugging starts from caller's frame.
         """
+        sys.settrace(None)
         if frame is None:
             frame = sys._getframe().f_back
         self.reset()
@@ -404,6 +406,14 @@ def set_break(self, filename, lineno, temporary=False, 
cond=None,
             return 'Line %s:%d does not exist' % (filename, lineno)
         self._add_to_breaks(filename, lineno)
         bp = Breakpoint(filename, lineno, temporary, cond, funcname)
+        # After we set a new breakpoint, we need to search through all frames
+        # and set f_trace to trace_dispatch if there could be a breakpoint in
+        # that frame.
+        frame = self.enterframe
+        while frame:
+            if self.break_anywhere(frame):
+                frame.f_trace = self.trace_dispatch
+            frame = frame.f_back
         return None
 
     def _load_breaks(self):
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 778aa03a63ab63..7a921a36b997f9 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -2371,6 +2371,36 @@ def test_issue26053(self):
         self.assertRegex(res, "Restarting .* with arguments:\na b c")
         self.assertRegex(res, "Restarting .* with arguments:\nd e f")
 
+    def test_issue58956(self):
+        # Set a breakpoint in a function that already exists on the call stack
+        # should enable the trace function for the frame.
+        script = """
+            import bar
+            def foo():
+                ret = bar.bar()
+                pass
+            foo()
+        """
+        commands = """
+            b bar.bar
+            c
+            b main.py:5
+            c
+            p ret
+            quit
+        """
+        bar = """
+            def bar():
+                return 42
+        """
+        with open('bar.py', 'w') as f:
+            f.write(textwrap.dedent(bar))
+        self.addCleanup(os_helper.unlink, 'bar.py')
+        stdout, stderr = self.run_pdb_script(script, commands)
+        lines = stdout.splitlines()
+        self.assertIn('-> pass', lines)
+        self.assertIn('(Pdb) 42', lines)
+
     def test_step_into_botframe(self):
         # gh-125422
         # pdb should not be able to step into the botframe (bdb.py)
diff --git 
a/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst 
b/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst
new file mode 100644
index 00000000000000..a882a632fddf1b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-09-24-18-16-59.gh-issue-58956.0wFrBR.rst
@@ -0,0 +1 @@
+Fixed a bug in :mod:`pdb` where sometimes the breakpoint won't trigger if it 
was set on a function which is already in the call stack.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to