From b8fa0bfa752bb672c66a1d6fdefcdf4cb308a712 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 14 Aug 2009 14:28:15 +0000 Subject: [PATCH] 2009-08-14 Pedro Alves gdb/ * top.c (any_thread_of): Delete. (kill_or_detach): Use any_thread_of_process. * top.c (print_inferior_quit_action): New. (quit_confirm): Rewrite to print info about all inferiors. * target.c (dispose_inferior): New. (target_preopen): Use it. 2009-08-14 Pedro Alves gdb/testsuite/ * gdb.threads/killed.exp, gdb.threads/manythreads.exp, gdb.threads/staticthreads.exp: Adjust to "quit" output changes. --- gdb/ChangeLog | 9 +++ gdb/target.c | 30 +++++++- gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.threads/killed.exp | 2 +- gdb/testsuite/gdb.threads/manythreads.exp | 2 +- gdb/testsuite/gdb.threads/staticthreads.exp | 2 +- gdb/top.c | 107 ++++++++++++++++------------ 7 files changed, 107 insertions(+), 50 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2a42ffe..297f57f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2009-08-14 Pedro Alves + * top.c (any_thread_of): Delete. + (kill_or_detach): Use any_thread_of_process. + * top.c (print_inferior_quit_action): New. + (quit_confirm): Rewrite to print info about all inferiors. + * target.c (dispose_inferior): New. + (target_preopen): Use it. + +2009-08-14 Pedro Alves + * ui-file.h (ui_file_xstrdup): Mention that the length argument may be NULL. * ui-file.c (ui_file_xstrdup): Don't dereference LENGTH if it is diff --git a/gdb/target.c b/gdb/target.c index 6a6c48e..7ee444f 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1904,6 +1904,29 @@ target_pre_inferior (int from_tty) } } +/* Callback for iterate_over_inferiors. Gets rid of the given + inferior. */ + +static int +dispose_inferior (struct inferior *inf, void *args) +{ + struct thread_info *thread; + + thread = any_thread_of_process (inf->pid); + if (thread) + { + switch_to_thread (thread->ptid); + + /* Core inferiors actually should be detached, not killed. */ + if (target_has_execution) + target_kill (); + else + target_detach (NULL, 0); + } + + return 0; +} + /* This is to be called by the open routine before it does anything. */ @@ -1912,11 +1935,12 @@ target_preopen (int from_tty) { dont_repeat (); - if (target_has_execution) + if (have_inferiors ()) { if (!from_tty - || query (_("A program is being debugged already. Kill it? "))) - target_kill (); + || !have_live_inferiors () + || query (_("A program is being debugged already. Kill it? "))) + iterate_over_inferiors (dispose_inferior, NULL); else error (_("Program not killed.")); } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0807d82..b56dfc4 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-08-14 Pedro Alves + + * gdb.threads/killed.exp, gdb.threads/manythreads.exp, + gdb.threads/staticthreads.exp: Adjust to "quit" output changes. + 2009-08-13 Pedro Alves * gdb.base/default.exp: Adjust "set language test": it's now an diff --git a/gdb/testsuite/gdb.threads/killed.exp b/gdb/testsuite/gdb.threads/killed.exp index 23f096c..3752a48 100644 --- a/gdb/testsuite/gdb.threads/killed.exp +++ b/gdb/testsuite/gdb.threads/killed.exp @@ -87,7 +87,7 @@ gdb_expect { # Try to quit. send_gdb "quit\n" gdb_expect { - -re "The program is running. Quit anyway \\(and kill it\\)\\? \\(y or n\\) $" { + -re "Quit anyway\\? \\(y or n\\) $" { send_gdb "y\n" exp_continue } diff --git a/gdb/testsuite/gdb.threads/manythreads.exp b/gdb/testsuite/gdb.threads/manythreads.exp index 5ded2c2..27d0996 100644 --- a/gdb/testsuite/gdb.threads/manythreads.exp +++ b/gdb/testsuite/gdb.threads/manythreads.exp @@ -160,7 +160,7 @@ gdb_test_multiple "" "stop threads 2" { } gdb_test_multiple "quit" "GDB exits after stopping multithreaded program" { - -re "The program is running. Quit anyway \\(and kill it\\)\\? \\(y or n\\) $" { + -re "Quit anyway\\? \\(y or n\\) $" { send_gdb "y\n" exp_continue } diff --git a/gdb/testsuite/gdb.threads/staticthreads.exp b/gdb/testsuite/gdb.threads/staticthreads.exp index 08000fd..fccb2e9 100644 --- a/gdb/testsuite/gdb.threads/staticthreads.exp +++ b/gdb/testsuite/gdb.threads/staticthreads.exp @@ -91,7 +91,7 @@ gdb_test_multiple "info threads" "$test" { set test "GDB exits with static thread program" gdb_test_multiple "quit" "$test" { - -re "The program is running. Quit anyway \\(and kill it\\)\\? \\(y or n\\) $" { + -re "Quit anyway\\? \\(y or n\\) $" { send_gdb "y\n" exp_continue } diff --git a/gdb/top.c b/gdb/top.c index de49418..cb51e08 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -1161,54 +1161,12 @@ set_prompt (char *s) } -/* If necessary, make the user confirm that we should quit. Return - non-zero if we should quit, zero if we shouldn't. */ - -int -quit_confirm (void) -{ - if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution) - { - char *s; - struct inferior *inf = current_inferior (); - - /* This is something of a hack. But there's no reliable way to - see if a GUI is running. The `use_windows' variable doesn't - cut it. */ - if (deprecated_init_ui_hook) - s = _("A debugging session is active.\nDo you still want to close the debugger?"); - else if (inf->attach_flag) - s = _("The program is running. Quit anyway (and detach it)? "); - else - s = _("The program is running. Quit anyway (and kill it)? "); - - if (!query ("%s", s)) - return 0; - } - - return 1; -} - struct qt_args { char *args; int from_tty; }; -/* Callback for iterate_over_threads. Finds any thread of inferior - given by ARG (really an int*). */ - -static int -any_thread_of (struct thread_info *thread, void *arg) -{ - int pid = * (int *)arg; - - if (PIDGET (thread->ptid) == pid) - return 1; - - return 0; -} - /* Callback for iterate_over_inferiors. Kills or detaches the given inferior, depending on how we originally gained control of it. */ @@ -1218,8 +1176,8 @@ kill_or_detach (struct inferior *inf, void *args) struct qt_args *qt = args; struct thread_info *thread; - thread = iterate_over_threads (any_thread_of, &inf->pid); - if (thread) + thread = any_thread_of_process (inf->pid); + if (thread != NULL) { switch_to_thread (thread->ptid); @@ -1236,6 +1194,67 @@ kill_or_detach (struct inferior *inf, void *args) return 0; } +/* Callback for iterate_over_inferiors. Prints info about what GDB + will do to each inferior on a "quit". ARG points to a struct + ui_out where output is to be collected. */ + +static int +print_inferior_quit_action (struct inferior *inf, void *arg) +{ + struct ui_file *stb = arg; + + if (inf->attach_flag) + fprintf_filtered (stb, + _("\tInferior %d [%s] will be detached.\n"), inf->num, + target_pid_to_str (pid_to_ptid (inf->pid))); + else + fprintf_filtered (stb, + _("\tInferior %d [%s] will be killed.\n"), inf->num, + target_pid_to_str (pid_to_ptid (inf->pid))); + + return 0; +} + +/* If necessary, make the user confirm that we should quit. Return + non-zero if we should quit, zero if we shouldn't. */ + +int +quit_confirm (void) +{ + struct ui_file *stb; + struct cleanup *old_chain; + char *str; + int qr; + + /* Don't even ask if we're only debugging a core file inferior. */ + if (!have_live_inferiors ()) + return 1; + + /* Build the query string as a single string. */ + stb = mem_fileopen (); + old_chain = make_cleanup_ui_file_delete (stb); + + /* This is something of a hack. But there's no reliable way to see + if a GUI is running. The `use_windows' variable doesn't cut + it. */ + if (deprecated_init_ui_hook) + fprintf_filtered (stb, _("A debugging session is active.\n" + "Do you still want to close the debugger?")); + else + { + fprintf_filtered (stb, _("A debugging session is active.\n\n")); + iterate_over_inferiors (print_inferior_quit_action, stb); + fprintf_filtered (stb, _("\nQuit anyway? ")); + } + + str = ui_file_xstrdup (stb, NULL); + make_cleanup (xfree, str); + + qr = query ("%s", str); + do_cleanups (old_chain); + return qr; +} + /* Helper routine for quit_force that requires error handling. */ static int -- 2.7.4