This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: ping: [patch 1/2] Fix gdb.cp/gdb2495.exp regression with gcc-4.7 #5
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: Joel Brobecker <brobecker at adacore dot com>
- Cc: Mark Kettenis <mark dot kettenis at xs4all dot nl>, gdb-patches at sourceware dot org
- Date: Mon, 11 Jun 2012 18:08:30 +0200
- Subject: Re: ping: [patch 1/2] Fix gdb.cp/gdb2495.exp regression with gcc-4.7 #5
- References: <20120309210045.GA30432@host2.jankratochvil.net> <20120326190355.GA11001@host2.jankratochvil.net> <201203261953.q2QJrXX4023325@glazunov.sibelius.xs4all.nl> <20120326203151.GA18085@host2.jankratochvil.net> <201203262145.q2QLjRIJ024024@glazunov.sibelius.xs4all.nl> <20120327081439.GA8387@host2.jankratochvil.net> <20120611152148.GA31854@adacore.com>
Hi,
On Mon, 11 Jun 2012 17:21:48 +0200, Joel Brobecker wrote:
> Does anyone have any comment on this patch from Jan? It has been
> identified as necessary before the release process gets started.
I am not sure what to do with it. I think it is definitely needed as without
this patch gdb.cp/gdb2495.exp regresses which is user visiable.
But it introduces the regression exploited by the testcase below. Using
infcalls may start to corrupt inferior stack. It is mentioned in the initial
post. Maybe "set breakpoint always-inserted on" would fix it but it would be
fragile having a stale breakpoint just relying nobody will ever reinsert it.
###
While there exist some ways how to prevent it - catching any longjmp and
re-checking any infcall breakpoints possibly becoming stale - it can be fooled
even some other ways. It would also have performance regression, with stale
infcall we would need to stop-and-continue for every longjmp (we do not
stop-and-continue during continue command in such case now).
But such stack re-checking is also not always good. In some cases we may just
fail to unwind the stack and in such moment GDB would remove the infcall
breakpoint. But in reality it would not be stale yet. While one can compare
some addresses in some case I was facing a problem of making arch-specific
assumptions in generic code.
I can try to implement the ### paragraph. Fedora already runs with this
patchset applied as is as it is less worse than not having it applied.
Thanks,
Jan
gdb/testsuite/
2012-06-11 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/stale-infcall.c: New file.
* gdb.base/stale-infcall.exp: New file.
diff --git a/gdb/testsuite/gdb.base/stale-infcall.c b/gdb/testsuite/gdb.base/stale-infcall.c
new file mode 100644
index 0000000..1f5169a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/stale-infcall.c
@@ -0,0 +1,63 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2012 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/>. */
+
+#include <setjmp.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define BUFSIZE 0x1000
+
+static jmp_buf jmp;
+
+void
+infcall (void)
+{
+ longjmp (jmp, 1);
+}
+
+static void
+run1 (void)
+{
+ char buf[BUFSIZE / 2];
+ int dummy = 0;
+
+ dummy++; /* break-run1 */
+}
+
+static char buf_zero[BUFSIZE];
+
+static void
+run2 (void)
+{
+ char buf[BUFSIZE];
+
+ memset (buf, 0, sizeof (buf));
+
+ if (memcmp (buf, buf_zero, sizeof (buf)) != 0) /* break-run2 */
+ abort (); /* break-fail */
+}
+
+int
+main ()
+{
+ if (setjmp (jmp) == 0)
+ run1 ();
+ else
+ run2 ();
+
+ return 0; /* break-exit */
+}
diff --git a/gdb/testsuite/gdb.base/stale-infcall.exp b/gdb/testsuite/gdb.base/stale-infcall.exp
new file mode 100644
index 0000000..ab7eaf0
--- /dev/null
+++ b/gdb/testsuite/gdb.base/stale-infcall.exp
@@ -0,0 +1,43 @@
+# Copyright (C) 2012 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/>.
+
+set testfile stale-infcall
+set srcfile ${testfile}.c
+if { [prepare_for_testing $testfile.exp $testfile $srcfile] } {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "break-run1"]
+gdb_breakpoint [gdb_get_line_number "break-run2"]
+gdb_breakpoint [gdb_get_line_number "break-exit"]
+gdb_breakpoint [gdb_get_line_number "break-fail"]
+
+gdb_continue_to_breakpoint "break-run1" ".* break-run1 .*"
+
+gdb_test "print infcall ()" " break-run2 .*The program being debugged stopped while in a function called from GDB\\..*When the function is done executing, GDB will silently stop\\."
+
+set test "stack corrupted"
+gdb_test_multiple "continue" $test {
+ -re " break-exit .*\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re " break-fail .*\r\n$gdb_prompt $" {
+ fail $test
+ }
+}