This is the mail archive of the mailing list for the GDB project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On Jul 30, 2012, at 4:25 PM, Tom Tromey wrote:

>>>>>> "Yit" == Khoo Yit Phang <> 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)".

July 30, 2012

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]