Python unwinder sniffer: PyExc_KeyboardInterrupt -> Quit
authorPedro Alves <palves@redhat.com>
Thu, 16 Nov 2017 18:44:44 +0000 (18:44 +0000)
committerPedro Alves <palves@redhat.com>
Thu, 16 Nov 2017 18:44:44 +0000 (18:44 +0000)
If you happen to press Ctrl-C while GDB is running the Python unwinder
machinery, the Ctrl-C is swallowed by the Python unwinder machinery.

For example, with:

 break foo
 commands
 > c
 > end

and

  while (1)
    foo ();

and then let the inferior hit "foo" repeatedly, sometimes Ctrl-C
results in:

~~~
  23        usleep (100);

  Breakpoint 2, foo () at gdb.base/bp-cmds-continue-ctrl-c.c:23
  23        usleep (100);
  ^C
  Breakpoint 2, Python Exception <class 'KeyboardInterrupt'> <class 'KeyboardInterrupt'>:
  foo () at gdb.base/bp-cmds-continue-ctrl-c.c:23
  23        usleep (100);

  Breakpoint 2, foo () at gdb.base/bp-cmds-continue-ctrl-c.c:23
  23        usleep (100);

  Breakpoint 2, foo () at gdb.base/bp-cmds-continue-ctrl-c.c:23
  23        usleep (100);
~~~

Notice the Python exception above.  The interesting thing here is that
GDB continues as if nothing happened, doesn't really stop and give
back control to the user.  Instead, the Ctrl-C aborted the Python
unwinder sniffer and GDB moved on to just use another unwinder.

Fix this by translating a PyExc_KeyboardInterrupt back into a Quit
exception once back in GDB.

This was exposed by the new gdb.base/bp-cmds-continue-ctrl-c.exp
testcase added later in the series.

gdb/ChangeLog:
2017-11-16  Pedro Alves  <palves@redhat.com>

* python/py-unwind.c (pyuw_sniffer): Translate
PyExc_KeyboardInterrupt to a GDB Quit exception.

gdb/ChangeLog
gdb/python/py-unwind.c

index b55ffdd..ab329df 100644 (file)
@@ -1,5 +1,10 @@
 2017-11-16  Pedro Alves  <palves@redhat.com>
 
+       * python/py-unwind.c (pyuw_sniffer): Translate
+       PyExc_KeyboardInterrupt to a GDB Quit exception.
+
+2017-11-16  Pedro Alves  <palves@redhat.com>
+
        * infrun.c (resume_cleanups): Delete.
        (resume): No longer install a resume_cleanups cleanup nor call
        QUIT.
index acfce7d..b578373 100644 (file)
@@ -539,6 +539,13 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
                                   pyo_pending_frame.get (), NULL));
   if (pyo_unwind_info == NULL)
     {
+      /* If the unwinder is cancelled due to a Ctrl-C, then propagate
+        the Ctrl-C as a GDB exception instead of swallowing it.  */
+      if (PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
+       {
+         PyErr_Clear ();
+         quit ();
+       }
       gdbpy_print_stack ();
       return 0;
     }