Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@adacore.com>
To: Pedro Alves <palves@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH v4 00/18] All-stop on top of non-stop
Date: Wed, 12 Aug 2015 18:32:00 -0000	[thread overview]
Message-ID: <20150812183208.GA24901@adacore.com> (raw)
In-Reply-To: <55C4E3BD.8040801@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1394 bytes --]

Hi Pedro,

On Fri, Aug 07, 2015 at 05:58:37PM +0100, Pedro Alves wrote:
> On 05/22/2015 12:18 AM, Pedro Alves wrote:
> > v3: https://sourceware.org/ml/gdb-patches/2015-04/msg00662.html
> > v2: https://sourceware.org/ml/gdb-patches/2015-04/msg00198.html
> > v1: https://sourceware.org/ml/gdb-patches/2015-04/msg00073.html
> > 
> > Compared to v3, a set of minor changes accumulated, to address review
> > comments and discussions (i.e., no major functional/design changes),
> > plus fixes to a patch that touched all targets (that I noticed
> > converted a couple wrong).
> > 
> > I believe I addressed all review comments thus far.  Barring comments,
> > I'd like to push this in, and expose it to the build bots.
> 
> FYI, I pushed this in.  I'm keeping an eye on the build bots.
> 
> If you spot any related problem, please confirm whether
> "maint set target-non-stop off" fixes it.

This uncovered what I think is a latent bug in the "how-did-we-never-
see-this-before" category. Does this patch look OK to you?

gdb/ChangeLog:

        * amd64-tdep.c (amd64_displaced_step_fixup): Fix the mask used to
        compute RETADDR.

gdb/testsuite/ChangeLog:

        * gdb.base/dso2dso-impl.c, gdb.base/dso2dso-impl.h,
        gdb.base/dso2dso-pck.c, gdb.base/dso2dso-pck.h, gdb.base/dso2dso.c,
        gdb.base/dso2dso.exp: New files.

Tested on x86_64-linux, no regression.

Thanks!
-- 
Joel

[-- Attachment #2: 0001-amd64-Invalid-return-address-after-displaced-steppin.patch --]
[-- Type: text/x-diff, Size: 12805 bytes --]

From 63cf63b54b7b303b07dcc3ab5206fef8b3bde418 Mon Sep 17 00:00:00 2001
From: Joel Brobecker <brobecker@adacore.com>
Date: Wed, 12 Aug 2015 09:33:19 -0700
Subject: [PATCH] [amd64] Invalid return address after displaced stepping

Making all-stop run on top of non-stop caused a small regression
in behavior. This was observed on x86_64-linux. The attached testcase
is in C whereas the investigation was done with an Ada program,
but it's the same scenario, and using a C testcase allows wider testing.
Basically: I am debugging a single-threaded program, and currently
stopped inside a function provided by a shared-library, at a line
calling a subprogram provided by a second shared library, and trying
to "next" over that function call.

Before we changed the default all-stop behavior, we had:

    7             Impl_Initialize;  -- Stop here and try "next" over this line
    (gdb) n
    8             return 5;  <<-- OK

But now, "next" just stops much earlier:

    (gdb) n
    0x00007ffff7bd8560 in impl.initialize@plt () from /[...]/lib/libpck.so

What happens is that next stops at a call instruction, which calls
the function's PLT, and GDB fails to notice that the inferior stepped
into a subroutine, and so decides that we're done. We can see another
symptom of the same issue by looking at the backtrace at the point
GDB stopped:

    (gdb) bt
    #0  0x00007ffff7bd8560 in impl.initialize@plt ()
       from /[...]/lib/libpck.so
    #1  0x00000000f7bd86f9 in ?? ()
    #2  0x00007fffffffdf50 in ?? ()
    #3  0x0000000000401893 in a () at /[...]/a.adb:7
    Backtrace stopped: frame did not save the PC

With a functioning GDB, the backtrace looks like the following instead:

    #0  0x00007ffff7bd8560 in impl.initialize@plt ()
       from /[...]/lib/libpck.so
    #1  0x00007ffff7bd86f9 in sub () at /[...]/pck.adb:7
    #2  0x0000000000401893 in a () at /[...]/a.adb:7

Note how, for frame #1, the address looks quite similar, except
for the high-order bits not being set:

    #1  0x00007ffff7bd86f9 in sub () at /[...]/pck.adb:7   <<<--  OK
    #1  0x00000000f7bd86f9 in ?? ()                        <<<--  WRONG
              ^^^^
              ||||
              Wrong

Investigating this further led me to displaced stepping.
As we are "next"-ing from a location where a breakpoint is inserted,
we need to step out of it, and since we're on non-stop mode, we need
to do it using displaced stepping. And looking at
amd64-tdep.c:amd64_displaced_step_fixup, I found the code that handles
the return address:

    regcache_cooked_read_unsigned (regs, AMD64_RSP_REGNUM, &rsp);
    retaddr = read_memory_unsigned_integer (rsp, retaddr_len, byte_order);
    retaddr = (retaddr - insn_offset) & 0xffffffffUL;

The mask used to compute retaddr looks wrong to me, keeping only
4 bytes instead of 8, and explains why the high order bits of
the backtrace are unset. What happens is that, after the displaced
stepping has completed, GDB restores that return address at the location
where the program expects it.  But because the top half bits of
the address have been masked out, the return address is now invalid.
The incorrect behavior of the "next" command and the backtrace at
that location are the first symptoms of that.  Another symptom is
that this actually alters the behavior of the program, where a "cont"
from there soon leads to a SEGV when the inferior tries to jump back
to that incorrect return address:

    (gdb) c
    Continuing.

    Program received signal SIGSEGV, Segmentation fault.
    0x00000000f7bd86f9 in ?? ()
    ^^^^^^^^^^^^^^^^^^

This patch fixes the issue by using a mask that seems more appropriate
for this architecture.

gdb/ChangeLog:

        * amd64-tdep.c (amd64_displaced_step_fixup): Fix the mask used to
        compute RETADDR.

gdb/testsuite/ChangeLog:

        * gdb.base/dso2dso-impl.c, gdb.base/dso2dso-impl.h,
        gdb.base/dso2dso-pck.c, gdb.base/dso2dso-pck.h, gdb.base/dso2dso.c,
        gdb.base/dso2dso.exp: New files.

Tested on x86_64-linux, no regression.
---
 gdb/amd64-tdep.c                      |  2 +-
 gdb/testsuite/gdb.base/dso2dso-impl.c | 24 +++++++++++++
 gdb/testsuite/gdb.base/dso2dso-impl.h | 23 +++++++++++++
 gdb/testsuite/gdb.base/dso2dso-pck.c  | 26 +++++++++++++++
 gdb/testsuite/gdb.base/dso2dso-pck.h  | 23 +++++++++++++
 gdb/testsuite/gdb.base/dso2dso.c      | 25 ++++++++++++++
 gdb/testsuite/gdb.base/dso2dso.exp    | 63 +++++++++++++++++++++++++++++++++++
 7 files changed, 185 insertions(+), 1 deletion(-)
 create mode 100644 gdb/testsuite/gdb.base/dso2dso-impl.c
 create mode 100644 gdb/testsuite/gdb.base/dso2dso-impl.h
 create mode 100644 gdb/testsuite/gdb.base/dso2dso-pck.c
 create mode 100644 gdb/testsuite/gdb.base/dso2dso-pck.h
 create mode 100644 gdb/testsuite/gdb.base/dso2dso.c
 create mode 100644 gdb/testsuite/gdb.base/dso2dso.exp

diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index 5e63b5e..5b4a8f4 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -1662,7 +1662,7 @@ amd64_displaced_step_fixup (struct gdbarch *gdbarch,
 
       regcache_cooked_read_unsigned (regs, AMD64_RSP_REGNUM, &rsp);
       retaddr = read_memory_unsigned_integer (rsp, retaddr_len, byte_order);
-      retaddr = (retaddr - insn_offset) & 0xffffffffUL;
+      retaddr = (retaddr - insn_offset) & 0xffffffffffffffffUL;
       write_memory_unsigned_integer (rsp, retaddr_len, byte_order, retaddr);
 
       if (debug_displaced)
diff --git a/gdb/testsuite/gdb.base/dso2dso-impl.c b/gdb/testsuite/gdb.base/dso2dso-impl.c
new file mode 100644
index 0000000..0b34aa9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dso2dso-impl.c
@@ -0,0 +1,24 @@
+/* Copyright 2015 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 "dso2dso-impl.h"
+
+void
+impl__initialize (void)
+{
+  /* Do nothing.  */
+}
diff --git a/gdb/testsuite/gdb.base/dso2dso-impl.h b/gdb/testsuite/gdb.base/dso2dso-impl.h
new file mode 100644
index 0000000..58b9d13
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dso2dso-impl.h
@@ -0,0 +1,23 @@
+/* Copyright 2015 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#ifndef DSO2DSO_IMPL_H
+#define DSO2DSO_IMPL_H
+
+extern void impl__initialize (void);
+
+#endif
diff --git a/gdb/testsuite/gdb.base/dso2dso-pck.c b/gdb/testsuite/gdb.base/dso2dso-pck.c
new file mode 100644
index 0000000..a6a38f9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dso2dso-pck.c
@@ -0,0 +1,26 @@
+/* Copyright 2015 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 "dso2dso-pck.h"
+#include "dso2dso-impl.h"
+
+int
+sub (void)
+{
+  impl__initialize ();
+  return 5;
+}
diff --git a/gdb/testsuite/gdb.base/dso2dso-pck.h b/gdb/testsuite/gdb.base/dso2dso-pck.h
new file mode 100644
index 0000000..11e8643
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dso2dso-pck.h
@@ -0,0 +1,23 @@
+/* Copyright 2015 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#ifndef DSO2DSO_PCK_H
+#define DSO2DSO_PCK_H
+
+extern int sub (void);
+
+#endif
diff --git a/gdb/testsuite/gdb.base/dso2dso.c b/gdb/testsuite/gdb.base/dso2dso.c
new file mode 100644
index 0000000..a085c00
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dso2dso.c
@@ -0,0 +1,25 @@
+/* Copyright 2015 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 "dso2dso-pck.h"
+
+int
+main (void)
+{
+  int ignored = sub ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/dso2dso.exp b/gdb/testsuite/gdb.base/dso2dso.exp
new file mode 100644
index 0000000..3d08b79
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dso2dso.exp
@@ -0,0 +1,63 @@
+# Copyright 2015 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/>.
+
+if { [skip_shlib_tests] } {
+    return 0
+}
+
+standard_testfile
+
+set output_dir [standard_output_file {}]
+
+set libimpl $testfile-impl
+set srcfile_libimpl $srcdir/$subdir/$libimpl.c
+set binfile_libimpl [standard_output_file $libimpl.so]
+
+set libpck $testfile-pck
+set srcfile_libpck $srcdir/$subdir/$libpck.c
+set binfile_libpck [standard_output_file $libpck.so]
+
+if { [gdb_compile_shlib $srcfile_libimpl $binfile_libimpl \
+	[list debug additional_flags=-fPIC]] != "" } {
+  untested "Could not compile $binfile_libimpl."
+  return -1
+}
+
+if { [gdb_compile_shlib $srcfile_libpck $binfile_libpck \
+	[list debug additional_flags=-fPIC]] != "" } {
+  untested "Could not compile $binfile_libpck."
+  return -1
+}
+
+if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable \
+	[list debug shlib=$binfile_libimpl shlib=$binfile_libpck]] != "" } {
+  return -1
+}
+
+clean_restart $binfile
+
+if { ![runto_main] } {
+  return -1
+}
+
+set bp_location [gdb_get_line_number "impl__initialize" $srcfile_libpck]
+gdb_breakpoint ${srcfile_libpck}:${bp_location}
+
+gdb_continue_to_breakpoint "at call to impl__initialize" \
+    ".*impl__initialize ().*"
+
+gdb_test "next" \
+    ".*return 5;.*" \
+    "next over call to impl__initialize"
-- 
2.1.4


  reply	other threads:[~2015-08-12 18:32 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-21 23:19 Pedro Alves
2015-05-21 23:19 ` [PATCH 01/18] Fix and test "checkpoint" in non-stop mode Pedro Alves
2015-05-21 23:19 ` [PATCH 06/18] Use keep_going in proceed and start_step_over too Pedro Alves
2015-05-21 23:19 ` [PATCH 18/18] native Linux: enable always non-stop by default Pedro Alves
2015-05-21 23:19 ` [PATCH 12/18] Fix signal-while-stepping-over-bp-other-thread.exp on targets always in non-stop Pedro Alves
2015-05-21 23:19 ` [PATCH 08/18] Add comments to currently_stepping and target_resume Pedro Alves
2015-05-21 23:19 ` [PATCH 14/18] Fix step-over-{trips-on-watchpoint|lands-on-breakpoint}.exp race Pedro Alves
2015-05-21 23:19 ` [PATCH 11/18] Implement all-stop on top of a target running non-stop mode Pedro Alves
2015-09-11 20:53   ` Jan Kratochvil
2015-09-14 14:24     ` Pedro Alves
2015-05-21 23:19 ` [PATCH 04/18] Make thread_still_needs_step_over consider stepping_over_watchpoint too Pedro Alves
2015-05-21 23:19 ` [PATCH 05/18] Embed the pending step-over chain in thread_info objects Pedro Alves
2015-05-21 23:19 ` [PATCH 03/18] remote.c/all-stop: Implement TARGET_WAITKIND_NO_RESUMED and TARGET_WNOHANG Pedro Alves
2015-05-21 23:19 ` [PATCH 02/18] Change adjust_pc_after_break's prototype Pedro Alves
2015-05-21 23:19 ` [PATCH 16/18] PPC64: Fix gdb.arch/ppc64-atomic-inst.exp with displaced stepping Pedro Alves
2015-05-21 23:19 ` [PATCH 09/18] Factor out code to re-resume stepped thread Pedro Alves
2015-05-21 23:25 ` [PATCH 07/18] Misc switch_back_to_stepped_thread cleanups Pedro Alves
2015-05-21 23:28 ` [PATCH 13/18] Fix interrupt-noterm.exp on targets always in non-stop Pedro Alves
2015-05-21 23:50 ` [PATCH 17/18] S/390: displaced stepping and PC-relative RIL-b/RIL-c instructions Pedro Alves
2015-05-21 23:56 ` [PATCH 10/18] Teach non-stop to do in-line step-overs (stop all, step, restart) Pedro Alves
2015-05-21 23:59 ` [PATCH 15/18] Disable displaced stepping if trying it fails Pedro Alves
2015-08-07 16:58 ` [PATCH v4 00/18] All-stop on top of non-stop Pedro Alves
2015-08-12 18:32   ` Joel Brobecker [this message]
2015-08-12 19:05     ` Pedro Alves
2015-08-12 20:26       ` Joel Brobecker
2015-08-12 20:31         ` Luis Machado
2015-08-12 20:50           ` Joel Brobecker
2015-08-12 21:07             ` Luis Machado
2015-08-13 16:04             ` Pedro Alves
2015-08-13 18:17               ` Joel Brobecker
2015-08-13 17:27         ` Pedro Alves
2015-08-13 18:29           ` Joel Brobecker
2015-08-12 19:39     ` Luis Machado
2015-08-12 19:51       ` Sergio Durigan Junior
2015-08-12 19:59       ` Joel Brobecker
2015-08-12 20:18         ` Luis Machado
2015-08-12 20:33           ` Joel Brobecker
2015-08-12 20:40             ` Luis Machado
2015-08-12 20:56               ` Joel Brobecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150812183208.GA24901@adacore.com \
    --to=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox