2008-11-13 Pedro Alves gdb/ * top.c (struct piqa_args): New. (print_inferior_quit_action): New. (quit_confirm): Rewrite to print info about all inferiors. 2008-11-13 Pedro Alves gdb/testsuite/ * gdb.threads/killed.exp, gdb.threads/manythreads.exp, gdb.threads/staticthreads.exp: Adjust. --- gdb/testsuite/gdb.threads/killed.exp | 2 gdb/testsuite/gdb.threads/manythreads.exp | 2 gdb/testsuite/gdb.threads/staticthreads.exp | 2 gdb/top.c | 143 ++++++++++++++++++++++------ 4 files changed, 118 insertions(+), 31 deletions(-) Index: src/gdb/top.c =================================================================== --- src.orig/gdb/top.c 2008-11-13 21:36:56.000000000 +0000 +++ src/gdb/top.c 2008-11-14 16:17:40.000000000 +0000 @@ -1176,34 +1176,6 @@ 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; @@ -1246,6 +1218,121 @@ kill_or_detach (struct inferior *inf, vo return 0; } +/* Arguments passed to print_inferior_quit_action. */ + +struct piqa_args +{ + /* Inferiors left to print, when this reaches 0, stop printing, and + start counting kills and detaches. */ + int slots_left; + + /* Number of inferiors that weren't printed, and going to be + killed. */ + int kills; + + /* Number of inferior that weren't printed, and are going to be + detached. */ + int detaches; + + /* Output is collected here. */ + struct ui_file *stb; +}; + +/* Callback for iterate_over_inferiors. Prints info about what GDB + will do to each inferior on a "quit". ARG points to a struct + piqa_args instance. */ + +static int +print_inferior_quit_action (struct inferior *inf, void *arg) +{ + struct piqa_args *args = arg; + + if (args->slots_left == 0) + { + if (inf->attach_flag) + args->detaches++; + else + args->kills++; + } + else + { + args->slots_left--; + + if (inf->attach_flag) + fprintf_filtered (args->stb, + _("\tInferior %d [%s] will be detached.\n"), inf->num, + target_pid_to_str (pid_to_ptid (inf->pid))); + else + fprintf_filtered (args->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) +{ + /* Don't ask if we're debugging a core file inferior. */ + if (have_inferiors () && target_has_execution) + { + struct piqa_args args = {0}; + struct cleanup *old_chain; + char *str; + long length; + int qr; + + /* The GUI will most likely place the whole query in a dialog + box. Make sure the query string is fully built as a single + string. */ + args.stb = mem_fileopen (); + old_chain = make_cleanup_ui_file_delete (args.stb); + + /* Don't print more than a few entries, in case the user is + trying to bail out with many inferiors and this paginates, or + if this is going to be displayed by a GUI in a dialog + box. */ + args.slots_left = 10; + + fprintf_filtered (args.stb, _("A debugging session is active.\n\n")); + + iterate_over_inferiors (print_inferior_quit_action, &args); + + /* Still give an idea what will happen to the rest of the + inferiors that weren't displayed. */ + if (args.kills != 0 && args.detaches != 0) + fprintf_filtered (args.stb, + _("\ +\n\t... %d inferior(s) more (of those, killing %d and detaching %d).\n"), + args.kills + args.detaches, + args.kills, args.detaches); + else if (args.kills != 0) + fprintf_filtered (args.stb, + _("\n\t... %d inferior(s) more will be killed.\n"), + args.kills); + else if (args.detaches != 0) + fprintf_filtered (args.stb, + _("\n\t... %d inferior(s) more will be detached.\n"), + args.detaches); + + fprintf_filtered (args.stb, + _("\nDo you still want to close the debugger? ")); + + str = ui_file_xstrdup (args.stb, &length); + make_cleanup (xfree, str); + + qr = query ("%s", str); + do_cleanups (old_chain); + return qr; + } + + return 1; +} + /* Helper routine for quit_force that requires error handling. */ static int Index: src/gdb/testsuite/gdb.threads/killed.exp =================================================================== --- src.orig/gdb/testsuite/gdb.threads/killed.exp 2008-11-13 21:36:56.000000000 +0000 +++ src/gdb/testsuite/gdb.threads/killed.exp 2008-11-13 21:36:57.000000000 +0000 @@ -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 "\\(y or n\\) $" { send_gdb "y\n" exp_continue } Index: src/gdb/testsuite/gdb.threads/manythreads.exp =================================================================== --- src.orig/gdb/testsuite/gdb.threads/manythreads.exp 2008-11-13 21:36:56.000000000 +0000 +++ src/gdb/testsuite/gdb.threads/manythreads.exp 2008-11-13 21:36:57.000000000 +0000 @@ -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 "\\(y or n\\) $" { send_gdb "y\n" exp_continue } Index: src/gdb/testsuite/gdb.threads/staticthreads.exp =================================================================== --- src.orig/gdb/testsuite/gdb.threads/staticthreads.exp 2008-11-13 21:36:56.000000000 +0000 +++ src/gdb/testsuite/gdb.threads/staticthreads.exp 2008-11-13 21:36:57.000000000 +0000 @@ -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 "\\(y or n\\) $" { send_gdb "y\n" exp_continue }