[PATCH 2/4]: Handle SIGINT under Python by raising KeyboardInterrupt

Khoo Yit Phang khooyp@cs.umd.edu
Thu Jul 26 21:41:00 GMT 2012


Hi,

On Jul 26, 2012, at 4:52 PM, Tom Tromey wrote:

>>>>>> "Yit" == Khoo Yit Phang <khooyp@cs.umd.edu> writes:
> 
> Yit> If I understand correctly, you're thinking of how to handle Ctrl-C
> Yit> that occurs in a Python context that should be treated as an interrupt
> Yit> in an outer GDB context, right? I think rather than setting quit_flag
> Yit> in the signal handler, we can catch KeyboardInterrupt after "python"
> Yit> returns, then set quit_flag there.
> 
> What I'd like to do, ideally, is make it so that when in a "gdb
> context", gdb-style SIGINT processing is done; and when in a "Python
> context", python-style is done.
> 
> The issue with auditing TRY_CATCH uses and only augmenting the "slow"
> ones is that the rest of gdb changes; loops and calls to QUIT are added;
> but it will be difficult to remember to update the Python layer.
> 
> I'm thinking now that we should perhaps have paired macros like:
> 
> #define PY_ENTER_GDB \
>  {  struct cleanup *try_cleanup = use_gdb_signals();
> 
> #define PY_LEAVE_GDB \
>     do_cleanups (try_cleanup); }

This seems reasonable, and would essentially just wrap my gdbpy_suspend_sigint_handler and gdbpy_resume_sigint_handler and other existing initialization/cleanup.

> Then just bracket all existing TRY_CATCH calls in python/*.c with those.
> Then this can just be a rule for future hacking on the python layer.
> 
> But it seems if we are going to do that we could go a bit further:
> 
> sig_atomic_t in_gdb;
> 
> #define PY_ENTER_GDB \
>  { in_gdb = 1;
> 
> #define PY_LEAVE_GDB \
>  gdb_check_quit_flag (); }
> 
> 
> Then have the signal handler we install for Python code do:
> 
>  if (in_gdb)
>     quit_flag = 1;
>  else
>     PyErr_SetInterrupt ();
> 
> ... and finally, have 
> 
> void gdb_check_quit_flag (void)
> {
>  in_gdb = 0;
>  if (quit_flag)
>    {
>      PyErr_SetInterrupt ();
>      quit_flag = 0;
>    }
> }

This assumes that GDB's SIGINT handler only sets quit_flag, and that GDB never changes the SIGINT handler and overrides the Python SIGINT handler? I vaguely recall encountering the latter issue which led me to the current implementation. A grep of GDB shows four places that call "signal (SIGINT, handle_sigint)" in event-top.c, record.c, and remote.c.

Yit
July 26, 2012



More information about the Gdb-patches mailing list