public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH v2 20/23] PPC64: symbol-file + exec-file results in broken displaced stepping
Date: Tue, 07 Apr 2015 12:50:00 -0000	[thread overview]
Message-ID: <1428410990-28560-21-git-send-email-palves@redhat.com> (raw)
In-Reply-To: <1428410990-28560-1-git-send-email-palves@redhat.com>

Running gdb.base/dbx.exp with "set displaced-stepping on" on PPC64
fails like this:

 (gdb) run
 Starting program: build/gdb/testsuite/gdb.base/dbx

 Program received signal SIGSEGV, Segmentation fault.
 __GI__dl_debug_state () at dl-debug.c:75
 75      {
 (gdb) FAIL: gdb.base/dbx.exp: running to main

The problem is that GDB ended up with the wrong entry point address.
Displaced stepping puts the scratch pad at the entry point, thus the
crash.

Most other tests load the binary into GDB with "file", which is just a
wrapper for "exec-file + symbol-file".  However, this particular test
does the opposite: first "symbol-file", and then "exec-file".

symfile.c:init_entry_point_info makes certain that the entry point
address points at real code, and not a function descriptor, by calling
gdbarch_convert_from_func_ptr_addr.  However, ppc64's implementation
of gdbarch_convert_from_func_ptr_addr relies on target sections.  IOW,
on the exec_file being loaded already.  Thus if we use just
"symbol-file PROG", ppc64_convert_from_func_ptr_addr can't check of
ADDR points to a function descriptor, and
symfile.c:init_entry_point_info ends up caching the wrong entry point
address in the OBJFILE.  Even if the user uses "exec-file" afterwards,
GDB doesn't fix up the objfile's entry point address, as the address
had already been initialized:

 static void
 init_entry_point_info (struct objfile *objfile)
 {
   struct entry_info *ei = &objfile->per_bfd->ei;

   if (ei->initialized)
     return;

I think that it's expected that "symbol-file" alone doesn't work,
however, I think "symbol-file" followed by "exec-file" should behave
the same as "exec-file + symbol-file".

This patch fixes it by making GDB forget about the previously cached
entry point address when a new exec file is loaded.  I didn't make
this gdbarch-dependent in order to keep it simple.

New test that doesn't depend on --dbx included.  Fails without the GDB
fix.

gdb/ChangeLog:
2015-04-07  Pedro Alves  <palves@redhat.com>

	* symfile.c (invalidate_symfile_entry_point_info): New function.
	(_initialize_symfile): Attach it as executable_changed observer.

gdb/testsuite/ChangeLog:
2015-04-07  Pedro Alves  <palves@redhat.com>

	* gdb.base/symbol-file-exec-file.c: New file.
	* gdb.base/symbol-file-exec-file.exp: New file.
---
 gdb/symfile.c                                    |  21 ++++
 gdb/testsuite/gdb.base/symbol-file-exec-file.c   |  30 ++++++
 gdb/testsuite/gdb.base/symbol-file-exec-file.exp | 126 +++++++++++++++++++++++
 3 files changed, 177 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/symbol-file-exec-file.c
 create mode 100644 gdb/testsuite/gdb.base/symbol-file-exec-file.exp

diff --git a/gdb/symfile.c b/gdb/symfile.c
index 0c35ffa..81244f7 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -900,6 +900,22 @@ read_symbols (struct objfile *objfile, int add_flags)
     require_partial_symbols (objfile, 0);
 }
 
+/* Forget about any previous computation of the main symfile's entry
+   point.  */
+
+static void
+invalidate_symfile_entry_point_info (void)
+{
+  struct entry_info *ei;
+
+  if (symfile_objfile == NULL)
+    return;
+
+  ei = &symfile_objfile->per_bfd->ei;
+  ei->initialized = 0;
+  ei->entry_point_p = 0;
+}
+
 /* Initialize entry point information for this objfile.  */
 
 static void
@@ -3957,6 +3973,11 @@ _initialize_symfile (void)
 
   observer_attach_free_objfile (symfile_free_objfile);
 
+  /* Some target's like PPC64 (see ppc64_convert_from_func_ptr_addr),
+     rely on the exec_file's target sections to compute the symfile's
+     entry point.  */
+  observer_attach_executable_changed (invalidate_symfile_entry_point_info);
+
   c = add_cmd ("symbol-file", class_files, symbol_file_command, _("\
 Load symbol table from executable file FILE.\n\
 The `file' command can also load symbol tables, as well as setting the file\n\
diff --git a/gdb/testsuite/gdb.base/symbol-file-exec-file.c b/gdb/testsuite/gdb.base/symbol-file-exec-file.c
new file mode 100644
index 0000000..0b37f46
--- /dev/null
+++ b/gdb/testsuite/gdb.base/symbol-file-exec-file.c
@@ -0,0 +1,30 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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/>.  */
+
+void
+foo (int i)
+{
+}
+
+int
+main (void)
+{
+  foo (1);
+  foo (2);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/symbol-file-exec-file.exp b/gdb/testsuite/gdb.base/symbol-file-exec-file.exp
new file mode 100644
index 0000000..aebf794
--- /dev/null
+++ b/gdb/testsuite/gdb.base/symbol-file-exec-file.exp
@@ -0,0 +1,126 @@
+# 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/>.
+
+# Test that displaced stepping works if the program is loaded with
+# "symbol-file + exec-file", in that order.  GDB used to end up with a
+# broken entry point address on PPC64 in that case.  (The displaced
+# stepping scratch pad is put at the entry point.)
+
+standard_testfile
+
+if {[build_executable "failed to build" $testfile $srcfile debug] == -1} {
+    return -1
+}
+
+# Override gdb_file_cmd, allowing gdb_load to do its normal thing.
+# This way remotes and simulators work, too.
+
+set old_gdb_file_cmd_args [info args gdb_file_cmd]
+set old_gdb_file_cmd_body [info body gdb_file_cmd]
+
+set our_gdb_file_cmd_called 0
+
+set symbol_file_first 0
+
+proc gdb_file_cmd {arg} {
+    upvar timeout timeout
+    global last_loaded_file
+    global our_gdb_file_cmd_called
+    global symbol_file_first
+
+    set our_gdb_file_cmd_called 1
+
+    set last_loaded_file $arg
+
+    if [is_remote host] {
+        set arg [remote_download host $arg]
+        if { $arg == "" } {
+            error "download failed"
+            return -1
+        }
+    }
+
+    proc symbol_file {} {
+	upvar arg arg
+
+	if {[gdb_test "symbol-file $arg" \
+		 "Reading symbols from.*done\\." \
+		 "symbol-file \$arg"] != 0 } {
+	    return -code return -1
+	}
+    }
+
+    proc exec_file {} {
+	upvar arg arg
+
+	if {[gdb_test_no_output "exec-file $arg" \
+		 "exec-file \$arg"] != 0} {
+	    return -code return -1
+	}
+    }
+
+    if $symbol_file_first {
+	symbol_file
+	exec_file
+    } else {
+	exec_file
+	symbol_file
+    }
+
+    return 0
+}
+
+# The test proper.  DISPLACED indicates whether to use displaced
+# stepping to step over the breakpoint.
+proc do_test { displaced } {
+    global our_gdb_file_cmd_called
+    global binfile
+
+    set our_gdb_file_cmd_called 0
+
+    clean_restart $binfile
+
+    gdb_test "set displaced-stepping $displaced"
+
+    # Don't rely on runto_main leaving the breakpoint behind.
+    gdb_breakpoint "main"
+
+    gdb_run_cmd
+
+    gdb_test "" "Breakpoint 1, main .* foo \\(1\\);" "run to main"
+
+    gdb_assert $our_gdb_file_cmd_called "overridden gdb_file_cmd called"
+
+    gdb_test "next" "foo \\(2\\);" "step over breakpoint"
+}
+
+foreach displaced { "off" "on" } {
+    foreach symfile_first { 0 1 } {
+	set symbol_file_first $symfile_first
+
+	if { $symfile_first } {
+	    set prefix "symbol-file + exec-file"
+	} else {
+	    set prefix "exec-file + symbol-file"
+	}
+
+	with_test_prefix "displaced=$displaced: $prefix" {
+	    do_test $displaced
+	}
+    }
+}
+
+# Restore gdb_file_cmd.
+eval proc gdb_file_cmd {$old_gdb_file_cmd_args} {$old_gdb_file_cmd_body}
-- 
1.9.3

  parent reply	other threads:[~2015-04-07 12:50 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-07 12:49 [PATCH v2 00/23] All-stop on top of non-stop Pedro Alves
2015-04-07 12:50 ` [PATCH v2 10/23] PPC64: Fix step-over-trips-on-watchpoint.exp with displaced stepping on Pedro Alves
2015-04-07 12:50 ` [PATCH v2 09/23] Make gdb.threads/step-over-trips-on-watchpoint.exp effective on !x86 Pedro Alves
2015-04-07 12:50 ` [PATCH v2 05/23] remote.c/all-stop: Implement TARGET_WAITKIND_NO_RESUMED and TARGET_WNOHANG Pedro Alves
2015-04-07 12:50 ` [PATCH v2 23/23] native Linux: enable always non-stop by default Pedro Alves
2015-04-07 12:50 ` [PATCH v2 19/23] Disable displaced stepping if trying it fails Pedro Alves
2015-04-07 12:50 ` [PATCH v2 03/23] PR13858 - Can't do displaced stepping with no symbols Pedro Alves
2015-04-09 12:46   ` Pedro Alves
2015-04-07 12:50 ` [PATCH v2 01/23] Fix gdb.base/sigstep.exp with displaced stepping on software single-step targets Pedro Alves
2015-04-10  9:56   ` Pedro Alves
2015-04-07 12:50 ` [PATCH v2 15/23] Implement all-stop on top of a target running non-stop mode Pedro Alves
2015-04-07 13:36   ` Eli Zaretskii
2015-04-08  9:34   ` Yao Qi
2015-04-08  9:53     ` Pedro Alves
2015-04-08 11:08       ` Pedro Alves
2015-04-08 19:35         ` Pedro Alves
2015-04-08 19:41           ` Pedro Alves
2015-04-07 12:50 ` [PATCH v2 16/23] Fix signal-while-stepping-over-bp-other-thread.exp on targets always in non-stop Pedro Alves
2015-04-07 12:50 ` [PATCH v2 02/23] Fix and test "checkpoint" in non-stop mode Pedro Alves
2015-04-07 12:50 ` [PATCH v2 21/23] PPC64: Fix gdb.arch/ppc64-atomic-inst.exp with displaced stepping Pedro Alves
2015-04-07 12:50 ` Pedro Alves [this message]
2015-04-07 12:50 ` [PATCH v2 12/23] Misc switch_back_to_stepped_thread cleanups Pedro Alves
2015-04-07 12:50 ` [PATCH v2 04/23] Change adjust_pc_after_break's prototype Pedro Alves
2015-04-07 12:50 ` [PATCH v2 11/23] Use keep_going in proceed and start_step_over too Pedro Alves
2015-04-07 12:50 ` [PATCH v2 22/23] S/390: displaced stepping and PC-relative RIL-b/RIL-c instructions Pedro Alves
2015-04-07 12:55 ` [PATCH v2 17/23] Fix interrupt-noterm.exp on targets always in non-stop Pedro Alves
2015-04-07 12:57 ` [PATCH v2 08/23] Test step-over-{lands-on-breakpoint|trips-on-watchpoint}.exp with displaced stepping Pedro Alves
2015-04-10 14:54   ` Pedro Alves
2015-04-07 12:59 ` [PATCH v2 14/23] Teach non-stop to do in-line step-overs (stop all, step, restart) Pedro Alves
2015-04-07 12:59 ` [PATCH v2 07/23] Embed the pending step-over chain in thread_info objects Pedro Alves
2015-04-07 12:59 ` [PATCH v2 13/23] Factor out code to re-resume stepped thread Pedro Alves
2015-04-07 13:30 ` [PATCH v2 06/23] Make thread_still_needs_step_over consider stepping_over_watchpoint too Pedro Alves
2015-04-08  9:28   ` Yao Qi
2015-04-13 10:47     ` Pedro Alves
2015-04-07 13:30 ` [PATCH v2 18/23] Fix step-over-{trips-on-watchpoint|lands-on-breakpoint}.exp race Pedro Alves
2015-04-08  9:45 ` [PATCH v2 00/23] All-stop on top of non-stop Yao Qi
2015-04-08 10:17   ` Pedro Alves
2015-04-08 10:30     ` Pedro Alves
2015-04-10  8:41     ` Yao Qi
2015-04-10  8:50       ` Pedro Alves
2015-04-10  8:22 ` Yao Qi
2015-04-10  8:34   ` Pedro Alves
2015-04-10  9:26     ` Yao Qi
2015-04-13 15:28       ` Pedro Alves
2015-04-13 16:16         ` Yao Qi
2015-04-13 16:23           ` Pedro Alves
2015-04-13 16:23           ` Pedro Alves

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=1428410990-28560-21-git-send-email-palves@redhat.com \
    --to=palves@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).