This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH 2/4]: Handle SIGINT under Python by raising KeyboardInterrupt
Hi,
On Jul 30, 2012, at 4:25 PM, Tom Tromey wrote:
>>>>>> "Yit" == Khoo Yit Phang <khooyp@cs.umd.edu> writes:
>
> Yit> It looks like this patch will work. I do need to make a change to my
> Yit> Python readline shim to call "while (gdb_do_one_event () >= 0)",
> Yit> otherwise the SIGINT will be processed twice: once by Python, and
> Yit> another time by GDB under gdb_readline_wrapper (since
> Yit> async_request_quit will be processed under gdb_do_one_event then, and
> Yit> immediate_quit is set).
>
> Hmm, to me this means something is wrong.
>
> Can you walk me through what happens here?
> I still don't understand.
>
> If SIGINT is seen while immediate_quit is set, the effect should be an
> immediate longjmp. In your patch this should be caught by the TRY_CATCH.
When you run "python-interactive" with my readline patches, it runs PyRun_InteractiveLoop that interactively takes user input via command_line_input (which eventually calls gdb_readline_wrapper) and evaluates it, e.g., if you type in something long running, say "for i in range(10000000): print i", it is returned by command_line_input to Python to be evaluated.
Then, while it is running, if you interrupt via Ctrl-C, handle_sigint calls PyErr_SetInterrupt and also registers async_request_quit via "gdb_call_async_signal_handler (sigint_token, immediate_quit)". Since we're still in the Python interpreter, it detects PyErr_SetInterrupt and processes it by raising KeyboardInterrupt, then calls command_line_input again. But at this point, async_request_quit has yet to be processed, because there are no calls to GDB's event loop until some point inside command_line_input (inside gdb_readline_wrapper). But immediate_quit is set by command_line_input, which causes async_request_quit to call quit (), which trips the TRY_CATCH in my readline wrapper and sets PyExc_KeyboardInterrupt, leading to a second exception.
It's seems strange to me that async_request_quit calls quit when either check_quit_flag or immediate_quit is true, since it leads to the possibility of quit being called twice, once if check_quit_flag is tested, e.g., via QUIT, and a second time by the start_event_loop or other calls to gdb_do_one_event, via "gdb_call_async_signal_handler (sigint_token, immediate_quit)".
Yit
July 30, 2012