From 522002f96cdfe306cb3385d075a5ae9f8381969e Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 22 Aug 2012 17:48:55 +0000 Subject: [PATCH] * defs.h (quit_flag): Don't declare. (clear_quit_flag, check_quit_flag, set_quit_flag): Declare. (QUIT): Use new functions. * event-top.c (command_handler): Use clear_quit_flag. (handle_sigint): Use set_quit_flag. (async_request_quit): Use check_quit_flag. Don't check immediate_quit. * exceptions.c (throw_exception): Use clear_quit_flag. * main.c (captured_main): Use clear_quit_flag. * python/python.c (clear_quit_flag, set_quit_flag) (check_quit_flag): New functions. * remote-sim.c (gdb_os_poll_quit): Use check_quit_flag, clear_quit_flag. * remote.c (remote_wait_as): Use check_quit_flag, clear_quit_flag. (remote_start_remote): Call QUIT. * symfile.c (load_progress): Use check_quit_flag. * top.c (command_loop): Use clear_quit_flag. (command_line_input): Call QUIT. * utils.c (quit_flag): Conditionally define. (clear_quit_flag, check_quit_flag, set_quit_flag): New functions. (prompt_for_continue): Call QUIT. Use quit, not async_request_quit. * remote-mips.c (mips_expect_timeout): Call QUIT. * monitor.c (monitor_expect): Call QUIT. --- gdb/ChangeLog | 29 +++++++++++++++++++++++++++++ gdb/defs.h | 24 ++++++++++++++++++++++-- gdb/event-top.c | 9 ++++----- gdb/exceptions.c | 2 +- gdb/main.c | 2 +- gdb/monitor.c | 1 + gdb/python/python.c | 25 +++++++++++++++++++++++++ gdb/remote-mips.c | 1 + gdb/remote-sim.c | 4 ++-- gdb/remote.c | 5 +++-- gdb/symfile.c | 2 +- gdb/top.c | 3 ++- gdb/utils.c | 40 +++++++++++++++++++++++++++++++++++++++- 13 files changed, 131 insertions(+), 16 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 97128a0f200..de3dbf550d6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,32 @@ +2012-08-22 Tom Tromey + + * defs.h (quit_flag): Don't declare. + (clear_quit_flag, check_quit_flag, set_quit_flag): Declare. + (QUIT): Use new functions. + * event-top.c (command_handler): Use clear_quit_flag. + (handle_sigint): Use set_quit_flag. + (async_request_quit): Use check_quit_flag. Don't check + immediate_quit. + * exceptions.c (throw_exception): Use clear_quit_flag. + * main.c (captured_main): Use clear_quit_flag. + * python/python.c (clear_quit_flag, set_quit_flag) + (check_quit_flag): New functions. + * remote-sim.c (gdb_os_poll_quit): Use check_quit_flag, + clear_quit_flag. + * remote.c (remote_wait_as): Use check_quit_flag, + clear_quit_flag. + (remote_start_remote): Call QUIT. + * symfile.c (load_progress): Use check_quit_flag. + * top.c (command_loop): Use clear_quit_flag. + (command_line_input): Call QUIT. + * utils.c (quit_flag): Conditionally define. + (clear_quit_flag, check_quit_flag, set_quit_flag): New + functions. + (prompt_for_continue): Call QUIT. Use quit, not + async_request_quit. + * remote-mips.c (mips_expect_timeout): Call QUIT. + * monitor.c (monitor_expect): Call QUIT. + 2012-08-22 Tom Tromey * event-top.c (sigwinch_token, handle_sigwinch): Remove. diff --git a/gdb/defs.h b/gdb/defs.h index de34740f323..96bc58c8b00 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -171,7 +171,27 @@ extern char *python_libdir; /* Search path for separate debug files. */ extern char *debug_file_directory; -extern int quit_flag; +/* GDB has two methods for handling SIGINT. When immediate_quit is + nonzero, a SIGINT results in an immediate longjmp out of the signal + handler. Otherwise, SIGINT simply sets a flag; code that might + take a long time, and which ought to be interruptible, checks this + flag using the QUIT macro. + + If GDB is built with Python support, it uses Python's low-level + interface to implement the flag. This approach makes it possible + for Python and GDB SIGINT handling to coexist seamlessly. + + If GDB is built without Python, it instead uses its traditional + variables. */ + +/* Clear the quit flag. */ +extern void clear_quit_flag (void); +/* Evaluate to non-zero if the quit flag is set, zero otherwise. This + will clear the quit flag as a side effect. */ +extern int check_quit_flag (void); +/* Set the quit flag. */ +extern void set_quit_flag (void); + extern int immediate_quit; extern void quit (void); @@ -184,7 +204,7 @@ extern void quit (void); needed. */ #define QUIT { \ - if (quit_flag) quit (); \ + if (check_quit_flag ()) quit (); \ if (deprecated_interactive_hook) deprecated_interactive_hook (); \ } diff --git a/gdb/event-top.c b/gdb/event-top.c index b4a67908595..4f3363c63ed 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -409,7 +409,7 @@ command_handler (char *command) int stdin_is_tty = ISATTY (stdin); struct cleanup *stat_chain; - quit_flag = 0; + clear_quit_flag (); if (instream == stdin && stdin_is_tty) reinitialize_more_filter (); @@ -788,7 +788,7 @@ handle_sigint (int sig) set quit_flag to 1 here. Then if QUIT is called before we get to the event loop, we will unwind as expected. */ - quit_flag = 1; + set_quit_flag (); /* If immediate_quit is set, we go ahead and process the SIGINT right away, even if we usually would defer this to the event loop. The @@ -817,10 +817,9 @@ async_request_quit (gdb_client_data arg) /* If the quit_flag has gotten reset back to 0 by the time we get back here, that means that an exception was thrown to unwind the current command before we got back to the event loop. So there - is no reason to call quit again here, unless immediate_quit is - set. */ + is no reason to call quit again here. */ - if (quit_flag || immediate_quit) + if (check_quit_flag ()) quit (); } diff --git a/gdb/exceptions.c b/gdb/exceptions.c index 7db9df9eb80..b7cf9a2cd8f 100644 --- a/gdb/exceptions.c +++ b/gdb/exceptions.c @@ -221,7 +221,7 @@ exceptions_state_mc_action_iter_1 (void) void throw_exception (struct gdb_exception exception) { - quit_flag = 0; + clear_quit_flag (); immediate_quit = 0; do_cleanups (all_cleanups ()); diff --git a/gdb/main.c b/gdb/main.c index d075694096b..326b101e54a 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -331,7 +331,7 @@ captured_main (void *data) dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg)); ndir = 0; - quit_flag = 0; + clear_quit_flag (); saved_command_line = (char *) xmalloc (saved_command_line_size); saved_command_line[0] = '\0'; instream = stdin; diff --git a/gdb/monitor.c b/gdb/monitor.c index d19a49ca5c5..48127364d66 100644 --- a/gdb/monitor.c +++ b/gdb/monitor.c @@ -512,6 +512,7 @@ monitor_expect (char *string, char *buf, int buflen) } immediate_quit++; + QUIT; while (1) { if (buf) diff --git a/gdb/python/python.c b/gdb/python/python.c index c66efe465e7..4a2b51885b4 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -151,6 +151,31 @@ ensure_python_env (struct gdbarch *gdbarch, return make_cleanup (restore_python_env, env); } +/* Clear the quit flag. */ + +void +clear_quit_flag (void) +{ + /* This clears the flag as a side effect. */ + PyOS_InterruptOccurred (); +} + +/* Set the quit flag. */ + +void +set_quit_flag (void) +{ + PyErr_SetInterrupt (); +} + +/* Return true if the quit flag has been set, false otherwise. */ + +int +check_quit_flag (void) +{ + return PyOS_InterruptOccurred (); +} + /* A wrapper around PyRun_SimpleFile. FILE is the Python script to run named FILENAME. diff --git a/gdb/remote-mips.c b/gdb/remote-mips.c index 7219bc76be1..eee2460ef3a 100644 --- a/gdb/remote-mips.c +++ b/gdb/remote-mips.c @@ -588,6 +588,7 @@ mips_expect_timeout (const char *string, int timeout) } immediate_quit++; + QUIT; while (1) { int c; diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index b3890b84269..87910d9cb51 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -950,9 +950,9 @@ gdb_os_poll_quit (host_callback *p) if (deprecated_ui_loop_hook != NULL) deprecated_ui_loop_hook (0); - if (quit_flag) /* gdb's idea of quit */ + if (check_quit_flag ()) /* gdb's idea of quit */ { - quit_flag = 0; /* we've stolen it */ + clear_quit_flag (); /* we've stolen it */ return 1; } return 0; diff --git a/gdb/remote.c b/gdb/remote.c index 3696709e4c3..2db2c9da469 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -3271,6 +3271,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p) char *wait_status = NULL; immediate_quit++; /* Allow user to interrupt it. */ + QUIT; if (interrupt_on_connect) send_interrupt_sequence (); @@ -5714,9 +5715,9 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options) ofunc = signal (SIGINT, remote_interrupt); /* If the user hit C-c before this packet, or between packets, pretend that it was hit right here. */ - if (quit_flag) + if (check_quit_flag ()) { - quit_flag = 0; + clear_quit_flag (); remote_interrupt (SIGINT); } } diff --git a/gdb/symfile.c b/gdb/symfile.c index a07f84c751b..6cac666f663 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1986,7 +1986,7 @@ load_progress (ULONGEST bytes, void *untyped_arg) args->buffer += bytes; totals->write_count += 1; args->section_sent += bytes; - if (quit_flag + if (check_quit_flag () || (deprecated_ui_load_progress_hook != NULL && deprecated_ui_load_progress_hook (args->section_name, args->section_sent))) diff --git a/gdb/top.c b/gdb/top.c index 8251d1b9d4c..7084116bbfb 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -569,7 +569,7 @@ command_loop (void) if (window_hook && instream == stdin) (*window_hook) (instream, get_prompt ()); - quit_flag = 0; + clear_quit_flag (); if (instream == stdin && stdin_is_tty) reinitialize_more_filter (); old_chain = make_cleanup (null_cleanup, 0); @@ -944,6 +944,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) /* Control-C quits instantly if typed while in this loop since it should not wait until the user types a newline. */ immediate_quit++; + QUIT; #ifdef STOP_SIGNAL if (job_control) signal (STOP_SIGNAL, handle_stop_sig); diff --git a/gdb/utils.c b/gdb/utils.c index b9e76ab76e0..6026450f16f 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -122,9 +122,11 @@ static int debug_timestamp = 0; int job_control; +#ifndef HAVE_PYTHON /* Nonzero means a quit has been requested. */ int quit_flag; +#endif /* HAVE_PYTHON */ /* Nonzero means quit immediately if Control-C is typed now, rather than waiting until QUIT is executed. Be careful in setting this; @@ -139,6 +141,41 @@ int quit_flag; int immediate_quit; +#ifndef HAVE_PYTHON + +/* Clear the quit flag. */ + +void +clear_quit_flag (void) +{ + quit_flag = 0; +} + +/* Set the quit flag. */ + +void +set_quit_flag (void) +{ + quit_flag = 1; +} + +/* Return true if the quit flag has been set, false otherwise. */ + +int +check_quit_flag (void) +{ + /* This is written in a particular way to avoid races. */ + if (quit_flag) + { + quit_flag = 0; + return 1; + } + + return 0; +} + +#endif /* HAVE_PYTHON */ + /* Nonzero means that strings with character values >0x7F should be printed as octal escapes. Zero means just print the value (e.g. it's an international character, and the terminal or window can cope.) */ @@ -1840,6 +1877,7 @@ prompt_for_continue (void) reinitialize_more_filter (); immediate_quit++; + QUIT; /* On a real operating system, the user can quit with SIGINT. But not on GO32. @@ -1868,7 +1906,7 @@ prompt_for_continue (void) while (*p == ' ' || *p == '\t') ++p; if (p[0] == 'q') - async_request_quit (0); + quit (); xfree (ignore); } immediate_quit--; -- 2.30.2