]> granicus.if.org Git - python/commitdiff
Issue #13120: Allow to call pdb.set_trace() from thread.
authorAndrew Svetlov <andrew.svetlov@gmail.com>
Tue, 4 Dec 2012 19:08:28 +0000 (21:08 +0200)
committerAndrew Svetlov <andrew.svetlov@gmail.com>
Tue, 4 Dec 2012 19:08:28 +0000 (21:08 +0200)
Patch by Ilya Sandler.

Lib/pdb.py
Lib/test/test_pdb.py
Misc/NEWS

index 6776a3f4cf65dd27e2f9793c218bbb680bebebc3..8c7c12b92cbe0e0e79ba506df685e6bdc0a56d4e 100755 (executable)
@@ -955,8 +955,15 @@ class Pdb(bdb.Bdb, cmd.Cmd):
         Continue execution, only stop when a breakpoint is encountered.
         """
         if not self.nosigint:
-            self._previous_sigint_handler = \
-                signal.signal(signal.SIGINT, self.sigint_handler)
+            try:
+                self._previous_sigint_handler = \
+                    signal.signal(signal.SIGINT, self.sigint_handler)
+            except ValueError:
+                # ValueError happens when do_continue() is invoked from
+                # a non-main thread in which case we just continue without
+                # SIGINT set. Would printing a message here (once) make
+                # sense?
+                pass
         self.set_continue()
         return 1
     do_c = do_cont = do_continue
index d28b0425e51d8946ecbc380c7ae4aea2c9b50fe7..dc2609e0c56b8b253f81b2299cf0a61c81628e22 100644 (file)
@@ -664,6 +664,33 @@ class PdbTestCase(unittest.TestCase):
             any('main.py(5)foo()->None' in l for l in stdout.splitlines()),
             'Fail to step into the caller after a return')
 
+    def test_issue13210(self):
+        # invoking "continue" on a non-main thread triggered an exception
+        # inside signal.signal
+
+        with open(support.TESTFN, 'wb') as f:
+            f.write(textwrap.dedent("""
+                import threading
+                import pdb
+
+                def start_pdb():
+                    pdb.Pdb().set_trace()
+                    x = 1
+                    y = 1
+
+                t = threading.Thread(target=start_pdb)
+                t.start()""").encode('ascii'))
+        cmd = [sys.executable, '-u', support.TESTFN]
+        proc = subprocess.Popen(cmd,
+            stdout=subprocess.PIPE,
+            stdin=subprocess.PIPE,
+            stderr=subprocess.STDOUT,
+            )
+        self.addCleanup(proc.stdout.close)
+        stdout, stderr = proc.communicate(b'cont\n')
+        self.assertNotIn('Error', stdout.decode(),
+                         "Got an error running test script under PDB")
+
     def tearDown(self):
         support.unlink(support.TESTFN)
 
index fbcfe90c0b717f81655efd0309421f4bb967ae2f..3894d2e3683a3ae29c653a5fea9fae0694920662 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -175,6 +175,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #13120: Allow to call pdb.set_trace() from thread.
+  Patch by Ilya Sandler.
+
 - Issue #10182: The re module doesn't truncate indices to 32 bits anymore.
   Patch by Serhiy Storchaka.