* [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies
@ 2013-03-15 19:55 Jan Kratochvil
2013-03-22 13:04 ` Pedro Alves
0 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2013-03-15 19:55 UTC (permalink / raw)
To: gdb-patches; +Cc: Hui Zhu
Hi,
there was a patch:
[RFA/tracepoint] Make GDB can work with some old GDB server
http://sourceware.org/ml/gdb-patches/2011-06/msg00368.html
http://sourceware.org/ml/gdb-patches/2011-07/msg00231.html
Message-ID: <BANLkTimuz12OVGoF9tKoV2ikcj9LKFax_g@mail.gmail.com>
872b7668686ffae68f1f3397de9d68512679e8e7
I did not try to find that kgdb but I made a reproducer with:
#--- a/gdb/gdbserver/tracepoint.c
#+++ b/gdb/gdbserver/tracepoint.c
#@@ -4203,7 +4203,8 @@ handle_tracepoint_query (char *packet)
# {
# if (strcmp ("qTStatus", packet) == 0)
# {
#- cmd_qtstatus (packet);
#+ strcpy (packet, "E22");
#+ if (0) cmd_qtstatus (packet);
# return 1;
# }
# else if (strncmp ("qTP:", packet, strlen ("qTP:")) == 0)
which does not work with Hui's original patch so probably kgdb behaves better
than this reproducer. This I believe if GDB survives this reproducer such GDB
should survive even kgdb.
By my change to the Hui's patch I caused a regression if gdbserver dies.
In such case GDB crashes as the "Remote connection closed" error gets filtered
out but the callers no longer have valid inferior and at least the proceed
function then crashes on stale local variable pointer. The original goal of
the "Remote connection closed" error was to completely abort the current
command.
#0 error (string=0xf5d5e0 "Remote connection closed") at utils.c:716
#1 in readchar (timeout=2) at remote.c:7051
#2 in getpkt_or_notif_sane_1 (buf=0x1eb8c60 <target_buf>, sizeof_buf=0x1eb8c68 <target_buf_size>, forever=0, expecting_notif=0, is_notif=0x0) at remote.c:7566
#3 in getpkt_sane (buf=0x1eb8c60 <target_buf>, sizeof_buf=0x1eb8c68 <target_buf_size>, forever=0) at remote.c:7664
#4 in getpkt (buf=0x1eb8c60 <target_buf>, sizeof_buf=0x1eb8c68 <target_buf_size>, forever=0) at remote.c:7506
#5 in remote_get_noisy_reply (buf_p=0x1eb8c60 <target_buf>, sizeof_buf=0x1eb8c68 <target_buf_size>) at remote.c:450
#6 in remote_get_trace_status (ts=0x1eba8a0 <trace_status>) at remote.c:10698
10696 TRY_CATCH (ex, RETURN_MASK_ERROR)
10698 p = remote_get_noisy_reply (&target_buf, &target_buf_size);
#7 in remote_can_download_tracepoint () at remote.c:10553
#8 in download_tracepoint_locations () at breakpoint.c:12174
#9 in update_global_location_list (should_insert=1) at breakpoint.c:12661
#10 in insert_breakpoints () at breakpoint.c:2732
#11 in proceed (addr=18446744073709551615, siggnal=GDB_SIGNAL_DEFAULT, step=1) at infrun.c:2243
#12 in step_once (skip_subroutines=0, single_inst=1, count=1, thread=-1) at infcmd.c:1092
#13 in step_1 (skip_subroutines=0, single_inst=1, count_string=0x0) at infcmd.c:927
#14 in stepi_command (count_string=0x0, from_tty=1) at infcmd.c:863
Therefore I limited the TRY_CATCH to 'E2...' errors which are reported as
"trace API error 0x%s." so it should hopefully fix the kgdb compatibility
problem without causing anything else.
No regressions on {x86_64,x86_64-m32,i686}-fedora19pre-linux-gnu and with
gdbserver.
Thanks,
Jan
gdb/
2013-03-15 Jan Kratochvil <jan.kratochvil@redhat.com>
* exceptions.h (enum errors): New entry TRACE_ERROR.
* remote.c (trace_error) <2>: Use throw_error for TRACE_ERROR.
(remote_get_trace_status): Call throw_exception if EX is not
TRACE_ERROR.
gdb/testsuite/
2013-03-15 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.server/server-kill.c: New file.
* gdb.server/server-kill.exp: New file.
diff --git a/gdb/exceptions.h b/gdb/exceptions.h
index 0d67719..b11af87 100644
--- a/gdb/exceptions.h
+++ b/gdb/exceptions.h
@@ -86,6 +86,9 @@ enum errors {
/* DW_OP_GNU_entry_value resolving failed. */
NO_ENTRY_VALUE_ERROR,
+ /* remote.c got error from remote end on trace packet. */
+ TRACE_ERROR,
+
/* Add more errors here. */
NR_ERRORS
};
diff --git a/gdb/remote.c b/gdb/remote.c
index 21d86f7..207180d 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -431,7 +431,7 @@ trace_error (char *buf)
error (_("remote.c: error in outgoing packet at field #%ld."),
strtol (buf, NULL, 16));
case '2':
- error (_("trace API error 0x%s."), ++buf);
+ throw_error (TRACE_ERROR, _("trace API error 0x%s."), ++buf);
default:
error (_("Target returns error code '%s'."), buf);
}
@@ -10703,8 +10699,12 @@ remote_get_trace_status (struct trace_status *ts)
}
if (ex.reason < 0)
{
- exception_fprintf (gdb_stderr, ex, "qTStatus: ");
- return -1;
+ if (ex.error == TRACE_ERROR)
+ {
+ exception_fprintf (gdb_stderr, ex, "qTStatus: ");
+ return -1;
+ }
+ throw_exception (ex);
}
/* If the remote target doesn't do tracing, flag it. */
diff --git a/gdb/testsuite/gdb.server/server-kill.c b/gdb/testsuite/gdb.server/server-kill.c
new file mode 100644
index 0000000..1949d64
--- /dev/null
+++ b/gdb/testsuite/gdb.server/server-kill.c
@@ -0,0 +1,24 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2013 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/>. */
+
+int
+main (void)
+{
+ int i = 0;
+
+ return i;
+}
diff --git a/gdb/testsuite/gdb.server/server-kill.exp b/gdb/testsuite/gdb.server/server-kill.exp
new file mode 100644
index 0000000..3bf5207
--- /dev/null
+++ b/gdb/testsuite/gdb.server/server-kill.exp
@@ -0,0 +1,55 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2013 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/>.
+
+load_lib gdbserver-support.exp
+
+standard_testfile
+
+if {[skip_gdbserver_tests]} {
+ return 0
+}
+
+if ![is_remote target] {
+ return 0
+}
+
+if { [target_info exists sockethost]
+ && [target_info sockethost] != "localhost:"
+ && [target_info sockethost] != "stdio" } {
+ # "remote_exec target" unsuccessfully tries "rsh" even with localhost.
+ # Therefore use "remote_exec host" instead limiting this testcase for
+ # testing on localhost only.
+ return 0
+}
+
+if { [prepare_for_testing ${testfile}.exp ${testfile}] } {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
+}
+
+# Otherwise the breakpoint at 'main' would not cause insert breakpoints during
+# first step.
+delete_breakpoints
+
+# It should be "remote_exec target" but it does not work, see above.
+set server_pid [exp_pid -i [board_info target fileid]]
+remote_exec host "kill -9 $server_pid"
+
+gdb_test "step" "Remote connection closed"
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-03-15 19:55 [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies Jan Kratochvil @ 2013-03-22 13:04 ` Pedro Alves 2013-03-22 20:29 ` Jan Kratochvil 0 siblings, 1 reply; 15+ messages in thread From: Pedro Alves @ 2013-03-22 13:04 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches, Hui Zhu On 03/15/2013 07:53 PM, Jan Kratochvil wrote: > there was a patch: > [RFA/tracepoint] Make GDB can work with some old GDB server > http://sourceware.org/ml/gdb-patches/2011-06/msg00368.html > http://sourceware.org/ml/gdb-patches/2011-07/msg00231.html > Message-ID: <BANLkTimuz12OVGoF9tKoV2ikcj9LKFax_g@mail.gmail.com> > 872b7668686ffae68f1f3397de9d68512679e8e7 Thanks. A bit of further background: http://sourceware.org/bugzilla/show_bug.cgi?id=12146 http://kerneltrap.org/mailarchive/linux-kernel/2010/7/22/4596723 The 22 in "E22" is not really a "trace api error" (whatever that meant for the original non-public tracepoint target in GDB years and years ago; the errors handled in trace_error are not really specified in the RSP docs). It just happened that kgdb leaked EINVAL (=22) to GDB whenever it got a packet that started with either "qf" or "qT" no matter if it was a tracing packet or not. The RSP-defined way to reply to unknown packets is to send back an empty reply, which GDB understands as "not supported". The kgdb bug was fixed back in 2010/07, with: commit fb82c0ff27b2c40c6f7a3d1a94cafb154591fa80 Author: Jason Wessel <jason.wessel@windriver.com> Date: Wed Jul 21 19:27:05 2010 -0500 repair gdbstub to match the gdbserial protocol specification The gdbserial protocol handler should return an empty packet instead of an error string when ever it responds to a command it does not implement. The problem cases come from a debugger client sending qTBuffer, qTStatus, qSearch, qSupported. The incorrect response from the gdbstub leads the debugger clients to not function correctly. Recent versions of gdb will not detach correctly as a result of this behavior. Signed-off-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com> I had closed PR 12146 as invalid back in 2010, because people that use kgdb are people hacking on the kernel, so if they stumble upon this kgdb bug, they should pull/merge the relevant kernel fix into their trees instead of gdb working around the kgdb bug. The PR shows an example of a reporter that was happy with that. I'd have the same opinion of Hui's patch in 2011 -- "fix your kernel instead". :-) Hui said back in 2011: "This is a bug of kgdb, but I think make gdb just output a warning is not affect anything else. So I make this patch." Clearly, it's showing now that it does affect some things. A couple of years more have passed, which makes the old kgdbs even less relevant, so IMO, we should just go ahead and revert the initial workaround. I checked that also fixes your new test. > By my change to the Hui's patch I caused a regression if gdbserver dies. > In such case GDB crashes as the "Remote connection closed" error gets filtered > out but the callers no longer have valid inferior and at least the proceed > function then crashes on stale local variable pointer. The original goal of > the "Remote connection closed" error was to completely abort the current > command. > > #0 error (string=0xf5d5e0 "Remote connection closed") at utils.c:716 > #1 in readchar (timeout=2) at remote.c:7051 > #2 in getpkt_or_notif_sane_1 (buf=0x1eb8c60 <target_buf>, sizeof_buf=0x1eb8c68 <target_buf_size>, forever=0, expecting_notif=0, is_notif=0x0) at remote.c:7566 > #3 in getpkt_sane (buf=0x1eb8c60 <target_buf>, sizeof_buf=0x1eb8c68 <target_buf_size>, forever=0) at remote.c:7664 > #4 in getpkt (buf=0x1eb8c60 <target_buf>, sizeof_buf=0x1eb8c68 <target_buf_size>, forever=0) at remote.c:7506 > #5 in remote_get_noisy_reply (buf_p=0x1eb8c60 <target_buf>, sizeof_buf=0x1eb8c68 <target_buf_size>) at remote.c:450 > #6 in remote_get_trace_status (ts=0x1eba8a0 <trace_status>) at remote.c:10698 > 10696 TRY_CATCH (ex, RETURN_MASK_ERROR) > 10698 p = remote_get_noisy_reply (&target_buf, &target_buf_size); > #7 in remote_can_download_tracepoint () at remote.c:10553 > #8 in download_tracepoint_locations () at breakpoint.c:12174 > #9 in update_global_location_list (should_insert=1) at breakpoint.c:12661 > #10 in insert_breakpoints () at breakpoint.c:2732 > #11 in proceed (addr=18446744073709551615, siggnal=GDB_SIGNAL_DEFAULT, step=1) at infrun.c:2243 > #12 in step_once (skip_subroutines=0, single_inst=1, count=1, thread=-1) at infcmd.c:1092 > #13 in step_1 (skip_subroutines=0, single_inst=1, count_string=0x0) at infcmd.c:927 > #14 in stepi_command (count_string=0x0, from_tty=1) at infcmd.c:863 > > Therefore I limited the TRY_CATCH to 'E2...' errors which are reported as > "trace API error 0x%s." so it should hopefully fix the kgdb compatibility > problem without causing anything else. If we went this path, I believe it would be the "connection closed" that should get special treatment as being a hard error that usually you'd want to propagate to some higher level and react by canceling all ongoing commands and cleaning up. I've occasionally thought of adding it on other occasions before. We should just eliminate trace_error -- it's magical error handling is meaningless today. > +load_lib gdbserver-support.exp > + > +standard_testfile > + > +if {[skip_gdbserver_tests]} { > + return 0 > +} > + > +if ![is_remote target] { > + return 0 > +} > + > +if { [target_info exists sockethost] > + && [target_info sockethost] != "localhost:" > + && [target_info sockethost] != "stdio" } { > + # "remote_exec target" unsuccessfully tries "rsh" even with localhost. > + # Therefore use "remote_exec host" instead limiting this testcase for > + # testing on localhost only. > + return 0 Hmm. Moved my ssh and rsh binaries from the path (well, renamed them) and did s/host/target/ below, and the test still worked. I wonder what's different in our environments? I'm testing with native-gdbserver.exp board in the tree. While at it, I tweaked the test to make it also work with the extended-remote-gdbserver.exp board like other test files handle it. See patch below. ------------------------------- gdb/ 2013-03-15 Pedro Alves <palves@redhat.com> * remote.c (remote_get_trace_status): Don't wrap remote_get_noisy_reply in TRY_CATCH. gdb/testsuite/ 2013-03-15 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> * gdb.server/server-kill.c: New file. * gdb.server/server-kill.exp: New file. --- gdb/testsuite/gdb.server/server-kill.c | 24 +++++++++++++++++ gdb/testsuite/gdb.server/server-kill.exp | 43 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 gdb/testsuite/gdb.server/server-kill.c create mode 100644 gdb/testsuite/gdb.server/server-kill.exp diff --git a/gdb/remote.c b/gdb/remote.c index 21d86f7..c682602 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -10696,16 +10696,7 @@ remote_get_trace_status (struct trace_status *ts) trace_regblock_size = get_remote_arch_state ()->sizeof_g_packet; putpkt ("qTStatus"); - - TRY_CATCH (ex, RETURN_MASK_ERROR) - { - p = remote_get_noisy_reply (&target_buf, &target_buf_size); - } - if (ex.reason < 0) - { - exception_fprintf (gdb_stderr, ex, "qTStatus: "); - return -1; - } + p = remote_get_noisy_reply (&target_buf, &target_buf_size); /* If the remote target doesn't do tracing, flag it. */ if (*p == '\0') diff --git a/gdb/testsuite/gdb.server/server-kill.c b/gdb/testsuite/gdb.server/server-kill.c new file mode 100644 index 0000000..1949d64 --- /dev/null +++ b/gdb/testsuite/gdb.server/server-kill.c @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 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/>. */ + +int +main (void) +{ + int i = 0; + + return i; +} diff --git a/gdb/testsuite/gdb.server/server-kill.exp b/gdb/testsuite/gdb.server/server-kill.exp new file mode 100644 index 0000000..45a2a89 --- /dev/null +++ b/gdb/testsuite/gdb.server/server-kill.exp @@ -0,0 +1,43 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2013 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/>. + +load_lib gdbserver-support.exp + +standard_testfile + +if {[skip_gdbserver_tests]} { + return 0 +} + +if { [prepare_for_testing ${testfile}.exp ${testfile}] } { + return -1 +} + +# Make sure we're disconnected, in case we're testing with an +# extended-remote board, therefore already connected. +gdb_test "disconnect" ".*" + +gdbserver_run "" + +# Otherwise the breakpoint at 'main' would not cause insert +# breakpoints during first step. +delete_breakpoints + +set server_pid [exp_pid -i [board_info target fileid]] +remote_exec target "kill -9 $server_pid" + +gdb_test "step" "Remote connection closed" ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-03-22 13:04 ` Pedro Alves @ 2013-03-22 20:29 ` Jan Kratochvil 2013-03-22 20:45 ` Pedro Alves 2013-04-08 7:17 ` [testsuite patch] race: server-kill.exp: Connection reset by peer [Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies] Jan Kratochvil 0 siblings, 2 replies; 15+ messages in thread From: Jan Kratochvil @ 2013-03-22 20:29 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Hui Zhu On Fri, 22 Mar 2013 13:39:11 +0100, Pedro Alves wrote: > The 22 in "E22" is not really a "trace api error" (whatever that > meant for the original non-public tracepoint target in GDB years and > years ago; the errors handled in trace_error are not really specified > in the RSP docs). It just happened that kgdb leaked > EINVAL (=22) In such case the patch should be limited specifically for E22, done. > I had closed PR 12146 as invalid back in 2010, because people that > use kgdb are people hacking on the kernel, so if they stumble upon > this kgdb bug, they should pull/merge the relevant kernel fix into > their trees instead of gdb working around the kgdb bug. [...] > A couple of years more have passed, which makes the old kgdbs even > less relevant, so IMO, we should just go ahead and revert the > initial workaround. Red Hat is actively supporting RHEL-5 linux-2.6.18 from 2006. It does not yet had kgdb but it illustrates other production systems with kernels from 2008..2010 may use kgdb. On production system one cannot feasibly change the kernel just because of a bugfix for debugging purposes. Therefore your patch will be a new regression against FSF GDB 7.5. People still face for example the bug new gdbserver is incompat. with old gdb - ;core: suffix http://sourceware.org/bugzilla/show_bug.cgi?id=15230 which is "fixed" in GDB (also) since 2010: commit 3d972c80ab566c07f5e55d356821fb883c9ade88 Date: Tue Jan 12 21:40:23 2010 +0000 As I said I leave gdbserver up to you but I do not much understand why to break compatibility when the fix is simple and done. > If we went this path, I believe it would be the "connection > closed" that should get special treatment as being a hard > error that usually you'd want to propagate to some higher > level and react by canceling all ongoing commands and cleaning > up. I've occasionally thought of adding it on other occasions > before. OK, done. > We should just eliminate trace_error -- it's magical error > handling is meaningless today. Done. > Hmm. Moved my ssh and rsh binaries from the path (well, renamed > them) and did s/host/target/ below, and the test still worked. > I wonder what's different in our environments? I was using old (and apparently incomplete) native-gdbserver.exp from the times it was still not a part of the FSF GDB tree. > While at it, I tweaked the test to make it also work with the > extended-remote-gdbserver.exp board like other test files handle it. Thanks. Jan gdb/ 2013-03-15 Jan Kratochvil <jan.kratochvil@redhat.com> * exceptions.h (enum errors): New entry TARGET_CLOSE_ERROR. * remote.c (trace_error): Remove the special handling of '2'. (readchar) <SERIAL_EOF> (readchar) <SERIAL_ERROR> (getpkt_or_notif_sane_1): Use TARGET_CLOSE_ERROR for them. (remote_get_trace_status): Call throw_exception if EX is TARGET_CLOSE_ERROR. * utils.c (perror_with_name): Rename to ... (throw_perror_with_name): ... here. New parameter errcode, describe it in the function comment. (perror_with_name): New function wrapper. * utils.h (enum errors): New stub declaration. (throw_perror_with_name): New declaration. gdb/testsuite/ 2013-03-22 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> * gdb.server/server-kill.c: New file. * gdb.server/server-kill.exp: New file. diff --git a/gdb/exceptions.h b/gdb/exceptions.h index 0d67719..630eb2e 100644 --- a/gdb/exceptions.h +++ b/gdb/exceptions.h @@ -86,6 +86,10 @@ enum errors { /* DW_OP_GNU_entry_value resolving failed. */ NO_ENTRY_VALUE_ERROR, + /* Target throwing an error has been closed. Current command should be + aborted as the inferior state is no longer valid. */ + TARGET_CLOSE_ERROR, + /* Add more errors here. */ NR_ERRORS }; diff --git a/gdb/remote.c b/gdb/remote.c index 21d86f7..c5bdc5d 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -430,8 +430,6 @@ trace_error (char *buf) else error (_("remote.c: error in outgoing packet at field #%ld."), strtol (buf, NULL, 16)); - case '2': - error (_("trace API error 0x%s."), ++buf); default: error (_("Target returns error code '%s'."), buf); } @@ -7052,12 +7050,13 @@ readchar (int timeout) { case SERIAL_EOF: pop_target (); - error (_("Remote connection closed")); + throw_error (TARGET_CLOSE_ERROR, _("Remote connection closed")); /* no return */ case SERIAL_ERROR: pop_target (); - perror_with_name (_("Remote communication error. " - "Target disconnected.")); + throw_perror_with_name (TARGET_CLOSE_ERROR, + _("Remote communication error. " + "Target disconnected.")); /* no return */ case SERIAL_TIMEOUT: break; @@ -7580,7 +7579,9 @@ getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever, { QUIT; pop_target (); - error (_("Watchdog timeout has expired. Target detached.")); + throw_error (TARGET_CLOSE_ERROR, + _("Watchdog timeout has expired. " + "Target detached.")); } if (remote_debug) fputs_filtered ("Timed out.\n", gdb_stdlog); @@ -10703,8 +10704,12 @@ remote_get_trace_status (struct trace_status *ts) } if (ex.reason < 0) { - exception_fprintf (gdb_stderr, ex, "qTStatus: "); - return -1; + if (ex.error != TARGET_CLOSE_ERROR) + { + exception_fprintf (gdb_stderr, ex, "qTStatus: "); + return -1; + } + throw_exception (ex); } /* If the remote target doesn't do tracing, flag it. */ diff --git a/gdb/utils.c b/gdb/utils.c index 4c2f08c..1fdc877 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -1077,11 +1077,11 @@ add_internal_problem_command (struct internal_problem *problem) } /* Print the system error message for errno, and also mention STRING - as the file name for which the error was encountered. - Then return to command level. */ + as the file name for which the error was encountered. Use ERRCODE + for the thrown exception. Then return to command level. */ void -perror_with_name (const char *string) +throw_perror_with_name (enum errors errcode, const char *string) { char *err; char *combined; @@ -1098,7 +1098,15 @@ perror_with_name (const char *string) bfd_set_error (bfd_error_no_error); errno = 0; - error (_("%s."), combined); + throw_error (errcode, _("%s."), combined); +} + +/* See throw_perror_with_name, ERRCODE defaults here to GENERIC_ERROR. */ + +void +perror_with_name (const char *string) +{ + throw_perror_with_name (GENERIC_ERROR, string); } /* Print the system error message for ERRCODE, and also mention STRING diff --git a/gdb/utils.h b/gdb/utils.h index 52bcaff..d6d49e6 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -279,6 +279,9 @@ extern char *hex_string_custom (LONGEST, int); extern void fprintf_symbol_filtered (struct ui_file *, const char *, enum language, int); +enum errors; +extern void throw_perror_with_name (enum errors errcode, const char *string) + ATTRIBUTE_NORETURN; extern void perror_with_name (const char *) ATTRIBUTE_NORETURN; extern void print_sys_errmsg (const char *, int); diff --git a/gdb/testsuite/gdb.server/server-kill.c b/gdb/testsuite/gdb.server/server-kill.c new file mode 100644 index 0000000..1949d64 --- /dev/null +++ b/gdb/testsuite/gdb.server/server-kill.c @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 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/>. */ + +int +main (void) +{ + int i = 0; + + return i; +} diff --git a/gdb/testsuite/gdb.server/server-kill.exp b/gdb/testsuite/gdb.server/server-kill.exp new file mode 100644 index 0000000..45a2a89 --- /dev/null +++ b/gdb/testsuite/gdb.server/server-kill.exp @@ -0,0 +1,43 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2013 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/>. + +load_lib gdbserver-support.exp + +standard_testfile + +if {[skip_gdbserver_tests]} { + return 0 +} + +if { [prepare_for_testing ${testfile}.exp ${testfile}] } { + return -1 +} + +# Make sure we're disconnected, in case we're testing with an +# extended-remote board, therefore already connected. +gdb_test "disconnect" ".*" + +gdbserver_run "" + +# Otherwise the breakpoint at 'main' would not cause insert +# breakpoints during first step. +delete_breakpoints + +set server_pid [exp_pid -i [board_info target fileid]] +remote_exec target "kill -9 $server_pid" + +gdb_test "step" "Remote connection closed" ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-03-22 20:29 ` Jan Kratochvil @ 2013-03-22 20:45 ` Pedro Alves 2013-03-22 20:55 ` Tom Tromey 2013-03-23 18:31 ` [commit+7.6] " Jan Kratochvil 2013-04-08 7:17 ` [testsuite patch] race: server-kill.exp: Connection reset by peer [Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies] Jan Kratochvil 1 sibling, 2 replies; 15+ messages in thread From: Pedro Alves @ 2013-03-22 20:45 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches, Hui Zhu On 03/22/2013 07:18 PM, Jan Kratochvil wrote: > On Fri, 22 Mar 2013 13:39:11 +0100, Pedro Alves wrote: >> The 22 in "E22" is not really a "trace api error" (whatever that >> meant for the original non-public tracepoint target in GDB years and >> years ago; the errors handled in trace_error are not really specified >> in the RSP docs). It just happened that kgdb leaked >> EINVAL (=22) > > In such case the patch should be limited specifically for E22, done. > > >> I had closed PR 12146 as invalid back in 2010, because people that >> use kgdb are people hacking on the kernel, so if they stumble upon >> this kgdb bug, they should pull/merge the relevant kernel fix into >> their trees instead of gdb working around the kgdb bug. > [...] >> A couple of years more have passed, which makes the old kgdbs even >> less relevant, so IMO, we should just go ahead and revert the >> initial workaround. > > Red Hat is actively supporting RHEL-5 linux-2.6.18 from 2006. It does not yet > had kgdb but it illustrates other production systems with kernels from > 2008..2010 may use kgdb. On production system one cannot feasibly change the > kernel just because of a bugfix for debugging purposes. Debugging a live production system with kgdb? I don't buy that, really. If one cares to debug the kernel with kgdb, then one can just as easily patch the kernel, just like one patches the kernel for security bugs and the like. It's not like the kernel is never ever updated on such systems. > Therefore your patch will be a new regression against FSF GDB 7.5. For people debugging the an old kernel with kgdb, the people that are fixing a bug or writing a driver and will end up patching the kernel... And the "regression" is only a problem for the subset of those that can't patch the kernel. Seems like the empty set to me. I don't know about the history of the original motivation for Hui's patch. Was pushback done to whoever found the issue, to see if the kernel could be fixed instead? Why couldn't that kernel be updated instead back then? > People still face for example the bug > new gdbserver is incompat. with old gdb - ;core: suffix > http://sourceware.org/bugzilla/show_bug.cgi?id=15230 > which is "fixed" in GDB (also) since 2010: > commit 3d972c80ab566c07f5e55d356821fb883c9ade88 > Date: Tue Jan 12 21:40:23 2010 +0000 > I've said before that I regret not having noticed that problem at patch review time or before the release. I still do. I don't see the parallel here though. We can't go back in time and fix older GDBs to cope with ;core... Users can upgrade their GDBs though. But let's not generalize. These problems need to be considered case by case, and my comments apply to particulars of the kgdb case, alone. > As I said I leave gdbserver up to you but I do not much understand why to > break compatibility when the fix is simple and done. Because it's a workaround that does not need to exist. It adds maintenance burden in the wrong place. The time we've wasted collectively iterating on this shows it. > > >> If we went this path, I believe it would be the "connection >> closed" that should get special treatment as being a hard >> error that usually you'd want to propagate to some higher >> level and react by canceling all ongoing commands and cleaning >> up. I've occasionally thought of adding it on other occasions >> before. > > OK, done. > > >> We should just eliminate trace_error -- it's magical error >> handling is meaningless today. > > Done. > I like this version much better than the original. If the exception swallowing ever turns out problematic again, I'll propose reverting the original patch again. So in interest of moving forward, this one's fine with me. -- Pedro Alves ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-03-22 20:45 ` Pedro Alves @ 2013-03-22 20:55 ` Tom Tromey 2013-03-23 10:51 ` Pedro Alves 2013-03-23 18:31 ` [commit+7.6] " Jan Kratochvil 1 sibling, 1 reply; 15+ messages in thread From: Tom Tromey @ 2013-03-22 20:55 UTC (permalink / raw) To: Pedro Alves; +Cc: Jan Kratochvil, gdb-patches, Hui Zhu >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> Debugging a live production system with kgdb? I don't buy Pedro> that, really. IIRC, this is the use case that tracepoints were designed for. So presumably it does happen. Tom ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-03-22 20:55 ` Tom Tromey @ 2013-03-23 10:51 ` Pedro Alves 2013-03-23 16:25 ` Tom Tromey 0 siblings, 1 reply; 15+ messages in thread From: Pedro Alves @ 2013-03-23 10:51 UTC (permalink / raw) To: Tom Tromey; +Cc: Jan Kratochvil, gdb-patches, Hui Zhu On 03/22/2013 08:00 PM, Tom Tromey wrote: >>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: > > Pedro> Debugging a live production system with kgdb? I don't buy > Pedro> that, really. > > IIRC, this is the use case that tracepoints were designed for. > So presumably it does happen. Hui's KGTP tracepoints stuff is not in mainline, and at least at the vintage of the broken kgdb, was not part of kgdb at all: http://www.sourceware.org/ml/gdb/2010-09/msg00134.html . It implements its own RSP handling. (I've never heard of Jim Blandy's previous effort for tracepoints in the kernel ending up used, or in production.) -- Pedro Alves ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-03-23 10:51 ` Pedro Alves @ 2013-03-23 16:25 ` Tom Tromey 0 siblings, 0 replies; 15+ messages in thread From: Tom Tromey @ 2013-03-23 16:25 UTC (permalink / raw) To: Pedro Alves; +Cc: Jan Kratochvil, gdb-patches, Hui Zhu Pedro> Hui's KGTP tracepoints stuff is not in mainline, and at least Pedro> at the vintage of the broken kgdb, was not part of kgdb at all: Ok, thanks. Tom ^ permalink raw reply [flat|nested] 15+ messages in thread
* [commit+7.6] [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-03-22 20:45 ` Pedro Alves 2013-03-22 20:55 ` Tom Tromey @ 2013-03-23 18:31 ` Jan Kratochvil 2013-03-23 22:49 ` Pedro Alves 2013-04-02 13:41 ` Yao Qi 1 sibling, 2 replies; 15+ messages in thread From: Jan Kratochvil @ 2013-03-23 18:31 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Hui Zhu On Fri, 22 Mar 2013 20:53:56 +0100, Pedro Alves wrote: > Debugging a live production system with kgdb? I don't buy > that, really. If one cares to debug the kernel with kgdb, then > one can just as easily patch the kernel, just like one patches the > kernel for security bugs and the like. This is becoming offtopic but the production systems I face are isolated from Internet and no security patches get ever applied. One of the many reasons is to keep all the systems the same, with interchangeable hard drives. > > People still face for example the bug > > new gdbserver is incompat. with old gdb - ;core: suffix > > http://sourceware.org/bugzilla/show_bug.cgi?id=15230 > > which is "fixed" in GDB (also) since 2010: > > commit 3d972c80ab566c07f5e55d356821fb883c9ade88 > > Date: Tue Jan 12 21:40:23 2010 +0000 > > > > I've said before that I regret not having noticed that problem > at patch review time or before the release. I still do. I don't > see the parallel here though. We can't go back in time and fix older > GDBs to cope with ;core... Users can upgrade their GDBs though. In practice in such cases people rather stay with older application, for whatever reason. > Because it's a workaround that does not need to exist. It adds > maintenance burden in the wrong place. The time we've wasted > collectively iterating on this shows it. Otherwise people would need to carry the workarounds downstream. So far I think upstream GDB is supporting workarounds of broken system components. > I like this version much better than the original. If the exception > swallowing ever turns out problematic again, I'll propose reverting > the original patch again. So in interest of moving forward, this one's > fine with me. Checked in: http://sourceware.org/ml/gdb-cvs/2013-03/msg00199.html and for 7.6: http://sourceware.org/ml/gdb-cvs/2013-03/msg00200.html Thanks, jan http://sourceware.org/ml/gdb-cvs/2013-03/msg00199.html --- src/gdb/ChangeLog 2013/03/22 20:25:40 1.15305 +++ src/gdb/ChangeLog 2013/03/22 20:39:28 1.15306 @@ -1,3 +1,19 @@ +2013-03-22 Jan Kratochvil <jan.kratochvil@redhat.com> + + * exceptions.h (enum errors): New entry TARGET_CLOSE_ERROR. + * remote.c (trace_error): Remove the special handling of '2'. + (readchar) <SERIAL_EOF> + (readchar) <SERIAL_ERROR> + (getpkt_or_notif_sane_1): Use TARGET_CLOSE_ERROR for them. + (remote_get_trace_status): Call throw_exception if EX is + TARGET_CLOSE_ERROR. + * utils.c (perror_with_name): Rename to ... + (throw_perror_with_name): ... here. New parameter errcode, describe it + in the function comment. + (perror_with_name): New function wrapper. + * utils.h (enum errors): New stub declaration. + (throw_perror_with_name): New declaration. + 2013-03-22 Pedro Alves <palves@redhat.com> Yao Qi <yao@codesourcery.com> Mark Kettenis <kettenis@gnu.org> --- src/gdb/testsuite/ChangeLog 2013/03/21 19:18:25 1.3594 +++ src/gdb/testsuite/ChangeLog 2013/03/22 20:39:28 1.3595 @@ -1,3 +1,9 @@ +2013-03-22 Jan Kratochvil <jan.kratochvil@redhat.com> + Pedro Alves <palves@redhat.com> + + * gdb.server/server-kill.c: New file. + * gdb.server/server-kill.exp: New file. + 2013-03-21 Pedro Alves <palves@redhat.com> * gdb.trace/trace-buffer-size.exp (get default buffer size): --- src/gdb/exceptions.h 2013/01/01 06:32:42 1.38 +++ src/gdb/exceptions.h 2013/03/22 20:39:28 1.39 @@ -86,6 +86,10 @@ /* DW_OP_GNU_entry_value resolving failed. */ NO_ENTRY_VALUE_ERROR, + /* Target throwing an error has been closed. Current command should be + aborted as the inferior state is no longer valid. */ + TARGET_CLOSE_ERROR, + /* Add more errors here. */ NR_ERRORS }; --- src/gdb/remote.c 2013/03/22 19:07:03 1.531 +++ src/gdb/remote.c 2013/03/22 20:39:28 1.532 @@ -430,8 +430,6 @@ else error (_("remote.c: error in outgoing packet at field #%ld."), strtol (buf, NULL, 16)); - case '2': - error (_("trace API error 0x%s."), ++buf); default: error (_("Target returns error code '%s'."), buf); } @@ -7048,12 +7046,13 @@ { case SERIAL_EOF: remote_unpush_target (); - error (_("Remote connection closed")); + throw_error (TARGET_CLOSE_ERROR, _("Remote connection closed")); /* no return */ case SERIAL_ERROR: remote_unpush_target (); - perror_with_name (_("Remote communication error. " - "Target disconnected.")); + throw_perror_with_name (TARGET_CLOSE_ERROR, + _("Remote communication error. " + "Target disconnected.")); /* no return */ case SERIAL_TIMEOUT: break; @@ -7576,7 +7575,9 @@ { QUIT; remote_unpush_target (); - error (_("Watchdog timeout has expired. Target detached.")); + throw_error (TARGET_CLOSE_ERROR, + _("Watchdog timeout has expired. " + "Target detached.")); } if (remote_debug) fputs_filtered ("Timed out.\n", gdb_stdlog); @@ -10699,8 +10700,12 @@ } if (ex.reason < 0) { - exception_fprintf (gdb_stderr, ex, "qTStatus: "); - return -1; + if (ex.error != TARGET_CLOSE_ERROR) + { + exception_fprintf (gdb_stderr, ex, "qTStatus: "); + return -1; + } + throw_exception (ex); } /* If the remote target doesn't do tracing, flag it. */ --- src/gdb/utils.c 2013/03/21 17:37:29 1.295 +++ src/gdb/utils.c 2013/03/22 20:39:28 1.296 @@ -966,11 +966,11 @@ } /* Print the system error message for errno, and also mention STRING - as the file name for which the error was encountered. - Then return to command level. */ + as the file name for which the error was encountered. Use ERRCODE + for the thrown exception. Then return to command level. */ void -perror_with_name (const char *string) +throw_perror_with_name (enum errors errcode, const char *string) { char *err; char *combined; @@ -987,7 +987,15 @@ bfd_set_error (bfd_error_no_error); errno = 0; - error (_("%s."), combined); + throw_error (errcode, _("%s."), combined); +} + +/* See throw_perror_with_name, ERRCODE defaults here to GENERIC_ERROR. */ + +void +perror_with_name (const char *string) +{ + throw_perror_with_name (GENERIC_ERROR, string); } /* Print the system error message for ERRCODE, and also mention STRING --- src/gdb/utils.h 2013/03/21 17:37:29 1.6 +++ src/gdb/utils.h 2013/03/22 20:39:28 1.7 @@ -278,6 +278,9 @@ extern void fprintf_symbol_filtered (struct ui_file *, const char *, enum language, int); +enum errors; +extern void throw_perror_with_name (enum errors errcode, const char *string) + ATTRIBUTE_NORETURN; extern void perror_with_name (const char *) ATTRIBUTE_NORETURN; extern void print_sys_errmsg (const char *, int); --- src/gdb/testsuite/gdb.server/server-kill.c +++ src/gdb/testsuite/gdb.server/server-kill.c 2013-03-22 20:42:07.933259467 +0000 @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 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/>. */ + +int +main (void) +{ + int i = 0; + + return i; +} --- src/gdb/testsuite/gdb.server/server-kill.exp +++ src/gdb/testsuite/gdb.server/server-kill.exp 2013-03-22 20:42:08.423295331 +0000 @@ -0,0 +1,43 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2013 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/>. + +load_lib gdbserver-support.exp + +standard_testfile + +if {[skip_gdbserver_tests]} { + return 0 +} + +if { [prepare_for_testing ${testfile}.exp ${testfile}] } { + return -1 +} + +# Make sure we're disconnected, in case we're testing with an +# extended-remote board, therefore already connected. +gdb_test "disconnect" ".*" + +gdbserver_run "" + +# Otherwise the breakpoint at 'main' would not cause insert +# breakpoints during first step. +delete_breakpoints + +set server_pid [exp_pid -i [board_info target fileid]] +remote_exec target "kill -9 $server_pid" + +gdb_test "step" "Remote connection closed" ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [commit+7.6] [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-03-23 18:31 ` [commit+7.6] " Jan Kratochvil @ 2013-03-23 22:49 ` Pedro Alves 2013-04-02 13:41 ` Yao Qi 1 sibling, 0 replies; 15+ messages in thread From: Pedro Alves @ 2013-03-23 22:49 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches, Hui Zhu On 03/22/2013 08:42 PM, Jan Kratochvil wrote: > On Fri, 22 Mar 2013 20:53:56 +0100, Pedro Alves wrote: >> Debugging a live production system with kgdb? I don't buy >> that, really. If one cares to debug the kernel with kgdb, then >> one can just as easily patch the kernel, just like one patches the >> kernel for security bugs and the like. > > This is becoming offtopic but the production systems I face are isolated from > Internet and no security patches get ever applied. One of the many reasons is > to keep all the systems the same, with interchangeable hard drives. > I'll eat my socks when you prove to me you've needed to debug one of those with a kgdb that is actually affected by this bug. ;-) > >>> People still face for example the bug >>> new gdbserver is incompat. with old gdb - ;core: suffix >>> http://sourceware.org/bugzilla/show_bug.cgi?id=15230 >>> which is "fixed" in GDB (also) since 2010: >>> commit 3d972c80ab566c07f5e55d356821fb883c9ade88 >>> Date: Tue Jan 12 21:40:23 2010 +0000 >>> >> >> I've said before that I regret not having noticed that problem >> at patch review time or before the release. I still do. I don't >> see the parallel here though. We can't go back in time and fix older >> GDBs to cope with ;core... Users can upgrade their GDBs though. > > In practice in such cases people rather stay with older application, for > whatever reason. Then if those people will prefer staying with older gdb and older gdbserver, fixing either gdb or gdbserver would do absolutely nothing for them. We can't rewrite history for them. >> Because it's a workaround that does not need to exist. It adds >> maintenance burden in the wrong place. The time we've wasted >> collectively iterating on this shows it. > > Otherwise people would need to carry the workarounds downstream. So far > I think upstream GDB is supporting workarounds of broken system components. Yes, when necessary. This was one case where my belief is it was not. But yes, let's move on. That old broken kgdb will get older over time, and at some point not even you will care. :-) >> I like this version much better than the original. If the exception >> swallowing ever turns out problematic again, I'll propose reverting >> the original patch again. So in interest of moving forward, this one's >> fine with me. > > Checked in: > http://sourceware.org/ml/gdb-cvs/2013-03/msg00199.html > and for 7.6: > http://sourceware.org/ml/gdb-cvs/2013-03/msg00200.html Thanks. I do believe the new exception will come in handy, so I'm glad to see that go in. -- Pedro Alves ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [commit+7.6] [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-03-23 18:31 ` [commit+7.6] " Jan Kratochvil 2013-03-23 22:49 ` Pedro Alves @ 2013-04-02 13:41 ` Yao Qi 2013-04-02 15:20 ` Jan Kratochvil 1 sibling, 1 reply; 15+ messages in thread From: Yao Qi @ 2013-04-02 13:41 UTC (permalink / raw) To: Jan Kratochvil; +Cc: Pedro Alves, gdb-patches, Hui Zhu On 03/23/2013 04:42 AM, Jan Kratochvil wrote: > +set server_pid [exp_pid -i [board_info target fileid]] > +remote_exec target "kill -9 $server_pid" > + > +gdb_test "step" "Remote connection closed" Jan, I got a fail in this test (on Lucid x86_64), Executing on native-gdbserver: kill -9 31336 {} {} {} (timeout = 300) spawn -ignore SIGHUP kill -9 31336 ^M kill: : invalid process id^M kill: : invalid process id^M kill: : invalid process id^M step^M Cannot find bounds of current function (gdb) FAIL: gdb.server/server-kill.exp: step The GDB's output of command 'step' is unexpected but looks reasonable to me. What we want to check here is GDB gets "connection closed" when GDBserver died, so any commands which talk with GDBserver should be qualified. I choose 'tstaus' here, because it simply talks with GDBserver to get trace status, and don't involve other factors into it. Note that we can use 'stepi' here, but I think 'tstatus' is simpler than it, so I choose 'tstatus' in the test finally. This patch fixes the fail I saw. Is it OK for mainline and 7.6? -- Yao (é½å°§) gdb/testsuite: 2013-04-02 Yao Qi <yao@codesourcery.com> * gdb.server/server-kill.exp: Use command 'tstatus' instead of 'step'. --- gdb/testsuite/gdb.server/server-kill.exp | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/gdb/testsuite/gdb.server/server-kill.exp b/gdb/testsuite/gdb.server/server-kill.exp index 45a2a89..1b48152 100644 --- a/gdb/testsuite/gdb.server/server-kill.exp +++ b/gdb/testsuite/gdb.server/server-kill.exp @@ -40,4 +40,6 @@ delete_breakpoints set server_pid [exp_pid -i [board_info target fileid]] remote_exec target "kill -9 $server_pid" -gdb_test "step" "Remote connection closed" +# Force GDB to talk with GDBserver, so that we can get the +# "connection closed" error. +gdb_test "tstatus" "Remote connection closed" -- 1.7.7.6 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [commit+7.6] [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-04-02 13:41 ` Yao Qi @ 2013-04-02 15:20 ` Jan Kratochvil 2013-04-04 11:09 ` Yao Qi 0 siblings, 1 reply; 15+ messages in thread From: Jan Kratochvil @ 2013-04-02 15:20 UTC (permalink / raw) To: Yao Qi; +Cc: Pedro Alves, gdb-patches, Hui Zhu On Tue, 02 Apr 2013 05:56:44 +0200, Yao Qi wrote: > This patch fixes the fail I saw. Is it OK for mainline and 7.6? [...] > * gdb.server/server-kill.exp: Use command 'tstatus' instead of > 'step'. Yes. Thanks, Jan ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [commit+7.6] [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies 2013-04-02 15:20 ` Jan Kratochvil @ 2013-04-04 11:09 ` Yao Qi 0 siblings, 0 replies; 15+ messages in thread From: Yao Qi @ 2013-04-04 11:09 UTC (permalink / raw) To: gdb-patches On 04/02/2013 09:53 PM, Jan Kratochvil wrote: > On Tue, 02 Apr 2013 05:56:44 +0200, Yao Qi wrote: >> This patch fixes the fail I saw. Is it OK for mainline and 7.6? > [...] >> * gdb.server/server-kill.exp: Use command 'tstatus' instead of >> 'step'. > > Yes. > > > Thanks, > Jan > Committed to the mainline and 7.6 branch. -- Yao (é½å°§) ^ permalink raw reply [flat|nested] 15+ messages in thread
* [testsuite patch] race: server-kill.exp: Connection reset by peer [Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies] 2013-03-22 20:29 ` Jan Kratochvil 2013-03-22 20:45 ` Pedro Alves @ 2013-04-08 7:17 ` Jan Kratochvil 2013-04-09 15:44 ` Pedro Alves 1 sibling, 1 reply; 15+ messages in thread From: Jan Kratochvil @ 2013-04-08 7:17 UTC (permalink / raw) To: gdb-patches; +Cc: Hui Zhu, Pedro Alves [-- Attachment #1: Type: text/plain, Size: 1919 bytes --] On Fri, 22 Mar 2013 20:18:41 +0100, Jan Kratochvil wrote: > +set server_pid [exp_pid -i [board_info target fileid]] > +remote_exec target "kill -9 $server_pid" > + > +gdb_test "step" "Remote connection closed" Getting occasionally randomly: Remote communication error. Target disconnected.: Connection reset by peer. (gdb) FAIL: gdb.server/server-kill.exp: tstatus (it was FAILing on "step" before, "tstatus" vs. "step" does not matter) I even Googled one may get ECONNRESET by writing into a closed TCP socket: http://stackoverflow.com/questions/2974021/what-does-econnreset-mean-in-the-context-of-an-af-local-socket But I was unable to reproduce it myself (kernel-3.8.4-202.fc18.x86_64) with the attached testcase: sleeping ... done write ok ssize=0 read ok send: send.c:53: main: Unexpected error: Broken pipe. Aborted by: * nc -l 5000 * ./send (starts sleeping) * kill -9 `pidof ncat` (Fedora nc is ncat) * # send resumes sleeping I get at most EPIPE but never ECONNRESET. send vs. write and recv vs. read also make no difference there. With no answer I will check in this patch as this issue seems unrelated to the problem, GDB still works properly even with ECONNRESET. I was just curious. Jan gdb/testsuite/ 2013-04-06 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.server/server-kill.exp (tstatus): Permit also ECONNRESET response. diff --git a/gdb/testsuite/gdb.server/server-kill.exp b/gdb/testsuite/gdb.server/server-kill.exp index 1b48152..75c9627 100644 --- a/gdb/testsuite/gdb.server/server-kill.exp +++ b/gdb/testsuite/gdb.server/server-kill.exp @@ -42,4 +42,4 @@ remote_exec target "kill -9 $server_pid" # Force GDB to talk with GDBserver, so that we can get the # "connection closed" error. -gdb_test "tstatus" "Remote connection closed" +gdb_test "tstatus" {Remote connection closed|Remote communication error\. Target disconnected\.: Connection reset by peer\.} [-- Attachment #2: send.c --] [-- Type: text/plain, Size: 1333 bytes --] #define _GNU_SOURCE 1 #include <sys/socket.h> #include <assert.h> #include <arpa/inet.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <signal.h> static volatile int piped; static void handler(int signo) { piped=1; } int main (void) { setbuf(stdout,NULL); signal(SIGPIPE,handler); int fd=socket(PF_INET,SOCK_STREAM,0); assert(fd!=-1); struct sockaddr_in addr; memset(&addr,0,sizeof addr); addr.sin_family=AF_INET; addr.sin_addr.s_addr=htonl(INADDR_LOOPBACK); addr.sin_port=htons(5000); int i=connect(fd,(struct sockaddr *)&addr,sizeof(addr)); assert(i==0); char charbuf='a'; ssize_t ssize=send(fd,&charbuf,1,0); assert(ssize==1); fputs("sleeping ...",stdout); sleep(5); charbuf='b'; puts(" done"); errno=0; // ssize=send(fd,&charbuf,1,0); ssize=write(fd,&charbuf,1); assert_perror(errno); assert(ssize==1); // puts("send ok"); puts("write ok"); errno=0; // ssize=recv(fd,&charbuf,1,0); ssize=read(fd,&charbuf,1); assert_perror(errno); printf("ssize=%zd\n",ssize); assert(ssize==0); // puts("recv ok"); puts("read ok"); errno=0; ssize=send(fd,&charbuf,1,0); // ssize=write(fd,&charbuf,1); assert_perror(errno); assert(ssize==1); puts("send ok"); // puts("write ok"); if (piped) puts("SIGPIPE"); return 0; } ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [testsuite patch] race: server-kill.exp: Connection reset by peer [Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies] 2013-04-08 7:17 ` [testsuite patch] race: server-kill.exp: Connection reset by peer [Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies] Jan Kratochvil @ 2013-04-09 15:44 ` Pedro Alves 2013-04-09 16:00 ` [commit+7.6] " Jan Kratochvil 0 siblings, 1 reply; 15+ messages in thread From: Pedro Alves @ 2013-04-09 15:44 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches, Hui Zhu [-- Attachment #1: Type: text/plain, Size: 1770 bytes --] On 04/06/2013 08:26 PM, Jan Kratochvil wrote: > On Fri, 22 Mar 2013 20:18:41 +0100, Jan Kratochvil wrote: >> +set server_pid [exp_pid -i [board_info target fileid]] >> +remote_exec target "kill -9 $server_pid" >> + >> +gdb_test "step" "Remote connection closed" > > Getting occasionally randomly: > Remote communication error. Target disconnected.: Connection reset by peer. > (gdb) FAIL: gdb.server/server-kill.exp: tstatus > > (it was FAILing on "step" before, "tstatus" vs. "step" does not matter) > > I even Googled one may get ECONNRESET by writing into a closed TCP socket: > http://stackoverflow.com/questions/2974021/what-does-econnreset-mean-in-the-context-of-an-af-local-socket > > But I was unable to reproduce it myself (kernel-3.8.4-202.fc18.x86_64) with > the attached testcase: > sleeping ... done > write ok > ssize=0 > read ok > send: send.c:53: main: Unexpected error: Broken pipe. > Aborted > by: > * nc -l 5000 > * ./send (starts sleeping) > * kill -9 `pidof ncat` (Fedora nc is ncat) > * # send resumes sleeping > > I get at most EPIPE but never ECONNRESET. send vs. write and recv vs. read > also make no difference there. From that url: "Triggered when there's outstanding outgoing data that has not yet been written to the other side." ncat is recv'ing the data you send it, so the window that could trigger is quite small. I've attached a standalone (no ncat) reproducer that triggers it all the time for me. $ ./send sleeping ... closing ... done send: send.c:72: main: Unexpected error: Connection reset by peer. Aborted > With no answer I will check in this patch as this issue seems unrelated to the > problem, GDB still works properly even with ECONNRESET. I was just curious. Looks fine to me. -- Pedro Alves [-- Attachment #2: send.c --] [-- Type: text/x-csrc, Size: 1725 bytes --] #define _GNU_SOURCE 1 #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/tcp.h> #include <assert.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #define PORT 5000 int main (void) { struct sockaddr_in sockaddr; socklen_t tmp; int listen_fd, send_fd, recv_fd; char charbuf; ssize_t ssize; int i; setbuf (stdout, NULL); /* bind/listen. */ errno = 0; listen_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); assert (listen_fd != -1); sockaddr.sin_family = PF_INET; sockaddr.sin_port = htons (PORT); sockaddr.sin_addr.s_addr = INADDR_ANY; if (bind (listen_fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) || listen (listen_fd, 1)) perror ("Can't bind address"); /* Connect. */ send_fd = socket (PF_INET,SOCK_STREAM, 0); assert (send_fd != -1); memset (&sockaddr, 0, sizeof sockaddr); sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); sockaddr.sin_port = htons (PORT); i = connect (send_fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)); assert (i == 0); /* Accept. */ tmp = sizeof (sockaddr); recv_fd = accept (listen_fd, (struct sockaddr *) &sockaddr, &tmp); assert (recv_fd != -1); /* Send. */ charbuf = 'a'; ssize = send (send_fd, &charbuf, 1, 0); assert (ssize == 1); /* Now that data has been queued, close the receiving end. */ fputs ("sleeping ...", stdout); sleep (1); fputs (" closing ...", stdout); close (recv_fd); sleep (1); puts (" done"); /* Try sending again. */ charbuf = 'b'; errno = 0; ssize = send (send_fd, &charbuf, 1, 0); assert_perror (errno); assert (ssize == 1); puts ("send ok"); return 0; } ^ permalink raw reply [flat|nested] 15+ messages in thread
* [commit+7.6] [testsuite patch] race: server-kill.exp: Connection reset by peer [Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies] 2013-04-09 15:44 ` Pedro Alves @ 2013-04-09 16:00 ` Jan Kratochvil 0 siblings, 0 replies; 15+ messages in thread From: Jan Kratochvil @ 2013-04-09 16:00 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Hui Zhu On Tue, 09 Apr 2013 17:23:03 +0200, Pedro Alves wrote: > "Triggered when there's outstanding outgoing data that has not yet been written to the other side." > > ncat is recv'ing the data you send it, so the window that > could trigger is quite small. oops, true. Thanks for the verification. > Looks fine to me. Checked in: http://sourceware.org/ml/gdb-cvs/2013-04/msg00091.html and also for 7.6 as it is very safe patch which may easy cross-version testing: http://sourceware.org/ml/gdb-cvs/2013-04/msg00092.html Thanks, Jan ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2013-04-09 15:28 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-03-15 19:55 [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies Jan Kratochvil 2013-03-22 13:04 ` Pedro Alves 2013-03-22 20:29 ` Jan Kratochvil 2013-03-22 20:45 ` Pedro Alves 2013-03-22 20:55 ` Tom Tromey 2013-03-23 10:51 ` Pedro Alves 2013-03-23 16:25 ` Tom Tromey 2013-03-23 18:31 ` [commit+7.6] " Jan Kratochvil 2013-03-23 22:49 ` Pedro Alves 2013-04-02 13:41 ` Yao Qi 2013-04-02 15:20 ` Jan Kratochvil 2013-04-04 11:09 ` Yao Qi 2013-04-08 7:17 ` [testsuite patch] race: server-kill.exp: Connection reset by peer [Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies] Jan Kratochvil 2013-04-09 15:44 ` Pedro Alves 2013-04-09 16:00 ` [commit+7.6] " Jan Kratochvil
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox