public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] [gdb/cli] Make quit really quit after remote connection closed
@ 2022-11-04 17:50 Tom de Vries
  2022-11-08 17:28 ` Tom Tromey
  0 siblings, 1 reply; 4+ messages in thread
From: Tom de Vries @ 2022-11-04 17:50 UTC (permalink / raw)
  To: gdb-patches

Consider a hello world a.out, started using gdbserver:
...
$ gdbserver --once 127.0.0.1:2345 ./a.out
Process ./a.out created; pid = 15743
Listening on port 2345
...
that we can connect to using gdb:
...
$ gdb -ex "target remote 127.0.0.1:2345"
Remote debugging using 127.0.0.1:2345
Reading /home/vries/a.out from remote target...
  ...
0x00007ffff7dd4550 in _start () from target:/lib64/ld-linux-x86-64.so.2
(gdb)
...

After that, we can for instance quit with confirmation:
...
(gdb) quit
A debugging session is active.

        Inferior 1 [process 16691] will be killed.

Quit anyway? (y or n) y
$
...

Or, kill with confirmation and quit:
...
(gdb) kill
Kill the program being debugged? (y or n) y
[Inferior 1 (process 16829) killed]
(gdb) quit
$
...

Or, monitor exit, kill with confirmation, and quit:
...
(gdb) monitor exit
(gdb) kill
Kill the program being debugged? (y or n) y
Remote connection closed
(gdb) quit
$
...

But when doing monitor exit followed by quit with confirmation, we get the gdb
prompt back, requiring us to do quit once more:
...
(gdb) monitor exit
(gdb) quit
A debugging session is active.

        Inferior 1 [process 16944] will be killed.

Quit anyway? (y or n) y
Remote connection closed
(gdb) quit
$
...

So, the first quit didn't quit.  This happens as follows:
- quit_command calls query_if_trace_running
- a TARGET_CLOSE_ERROR is thrown
- it's caught in remote_target::get_trace_status, but then
  rethrown because it's TARGET_CLOSE_ERROR
- catch_command_errors catches the error, at which point the quit command
  has been aborted.

The TARGET_CLOSE_ERROR is defined as:
...
  /* Target throwing an error has been closed.  Current command should be
     aborted as the inferior state is no longer valid.  */
  TARGET_CLOSE_ERROR,
...
so in a way this is expected behaviour.  But aborting quit because the inferior
state (which we've already confirmed we're not interested in) is no longer
valid, and having to type quit again seems pointless.

Furthermore, the purpose of not catching errors thrown by
query_if_trace_running as per commit 2f9d54cfcef ("make -gdb-exit call
 disconnect_tracing too, and don't lose history if the target errors on
"quit""), was to make sure that error (_("Not confirmed.") had effect.

Fix this in quit_command by catching only the TARGET_CLOSE_ERROR exception
during query_if_trace_running and reporting it:
...
(gdb) monitor exit
(gdb) quit
A debugging session is active.

        Inferior 1 [process 19219] will be killed.

Quit anyway? (y or n) y
Remote connection closed
$
...

Tested on x86_64-linux.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=15746
---
 gdb/cli/cli-cmds.c                            | 15 +++-
 .../gdb.server/monitor-exit-quit.exp          | 81 +++++++++++++++++++
 2 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 gdb/testsuite/gdb.server/monitor-exit-quit.exp

diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index fe4041662ef..bcfd3641ef5 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -488,7 +488,20 @@ quit_command (const char *args, int from_tty)
   if (!quit_confirm ())
     error (_("Not confirmed."));
 
-  query_if_trace_running (from_tty);
+  try
+    {
+      query_if_trace_running (from_tty);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      if (ex.error == TARGET_CLOSE_ERROR)
+	/* We don't care about this since we're quitting anyway, so keep
+	   quitting.  */
+	exception_print (gdb_stderr, ex);
+      else
+	/* Rethrow, to properly handle error (_("Not confirmed.")).  */
+	throw;
+    }
 
   quit_force (args ? &exit_code : NULL, from_tty);
 }
diff --git a/gdb/testsuite/gdb.server/monitor-exit-quit.exp b/gdb/testsuite/gdb.server/monitor-exit-quit.exp
new file mode 100644
index 00000000000..fdf24520989
--- /dev/null
+++ b/gdb/testsuite/gdb.server/monitor-exit-quit.exp
@@ -0,0 +1,81 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test quitting after monitor exit.
+
+load_lib gdbserver-support.exp
+
+standard_testfile server.c
+
+if { [skip_gdbserver_tests] } {
+    return 0
+}
+
+if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
+    return -1
+}
+
+save_vars { GDBFLAGS } {
+    # If GDB and GDBserver are both running locally, set the sysroot to avoid
+    # reading files via the remote protocol.
+    if { ![is_remote host] && ![is_remote target] } {
+	set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\""
+    }
+
+    clean_restart $binfile
+}
+
+# Make sure we're disconnected, in case we're testing with an
+# extended-remote board, therefore already connected.
+gdb_test "disconnect" ".*"
+
+set target_exec [gdbserver_download_current_prog]
+
+set res [gdbserver_start "" $target_exec]
+
+set gdbserver_protocol [lindex $res 0]
+set gdbserver_gdbport [lindex $res 1]
+gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
+
+gdb_test_no_output "monitor exit"
+gdb_test_no_output "set confirm off"
+
+set do_cleanup 1
+
+gdb_test_multiple "quit" "" {
+    -re -wrap "" {
+	fail "$gdb_test_name (prompt)"
+	# Let default_gdb_exit do the cleanup.
+	set do_cleanup 0
+    }
+    -early -re "DOSEXIT code" {
+	pass "$gdb_test_name"
+    }
+    -early eof {
+	pass "$gdb_test_name"
+    }
+}
+
+# Cleanup, as in default_gdb_exit.
+if { $do_cleanup } {
+    if ![is_remote host] {
+	    remote_close host
+    }
+    unset gdb_spawn_id
+    unset ::gdb_tty_name
+    unset inferior_spawn_id
+}

base-commit: ac87b20a96adec653af45253fc3b2daf1a0710eb
-- 
2.35.3


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] [gdb/cli] Make quit really quit after remote connection closed
  2022-11-04 17:50 [PATCH] [gdb/cli] Make quit really quit after remote connection closed Tom de Vries
@ 2022-11-08 17:28 ` Tom Tromey
  2022-11-08 17:52   ` Tom de Vries
  0 siblings, 1 reply; 4+ messages in thread
From: Tom Tromey @ 2022-11-08 17:28 UTC (permalink / raw)
  To: Tom de Vries via Gdb-patches; +Cc: Tom de Vries

>>>>> "Tom" == Tom de Vries via Gdb-patches <gdb-patches@sourceware.org> writes:

Tom> But when doing monitor exit followed by quit with confirmation, we get the gdb
Tom> prompt back, requiring us to do quit once more:

Thanks for doing this.

Tom> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=15746

I think mentioning "PR server/15746" in the commit message would cause
this to show up in bugzilla.

Other than that, this looks good to me.

Tom

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] [gdb/cli] Make quit really quit after remote connection closed
  2022-11-08 17:28 ` Tom Tromey
@ 2022-11-08 17:52   ` Tom de Vries
  2022-11-08 19:40     ` Tom Tromey
  0 siblings, 1 reply; 4+ messages in thread
From: Tom de Vries @ 2022-11-08 17:52 UTC (permalink / raw)
  To: Tom Tromey, Tom de Vries via Gdb-patches

On 11/8/22 18:28, Tom Tromey wrote:
>>>>>> "Tom" == Tom de Vries via Gdb-patches <gdb-patches@sourceware.org> writes:
> 
> Tom> But when doing monitor exit followed by quit with confirmation, we get the gdb
> Tom> prompt back, requiring us to do quit once more:
> 
> Thanks for doing this.
> 
> Tom> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=15746
> 
> I think mentioning "PR server/15746" in the commit message would cause
> this to show up in bugzilla.
> 

I've tried that, but that didn't seem to work.  Maybe I need to wait 
longer, I'm not sure.

> Other than that, this looks good to me.

thanks for the review, committed.

- Tom

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] [gdb/cli] Make quit really quit after remote connection closed
  2022-11-08 17:52   ` Tom de Vries
@ 2022-11-08 19:40     ` Tom Tromey
  0 siblings, 0 replies; 4+ messages in thread
From: Tom Tromey @ 2022-11-08 19:40 UTC (permalink / raw)
  To: Tom de Vries via Gdb-patches; +Cc: Tom Tromey, Tom de Vries

>> I think mentioning "PR server/15746" in the commit message would
>> cause this to show up in bugzilla.

Tom> I've tried that, but that didn't seem to work.  Maybe I need to wait
Tom> longer, I'm not sure.

It's usually pretty quick.  I looked now and it did show up,
https://sourceware.org/bugzilla/show_bug.cgi?id=15746#c7

Tom

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-11-08 19:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-04 17:50 [PATCH] [gdb/cli] Make quit really quit after remote connection closed Tom de Vries
2022-11-08 17:28 ` Tom Tromey
2022-11-08 17:52   ` Tom de Vries
2022-11-08 19:40     ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).