public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
To: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Cc: Andrew Burgess <aburgess@redhat.com>,
	Guinevere Larsen <blarsen@redhat.com>
Subject: [PATCH v5 1/3] Fix handling of DW_AT_entry_pc of inlined subroutines
Date: Mon, 2 Sep 2024 16:57:10 +0200	[thread overview]
Message-ID: <AS1PR01MB94659E4D9B3F4A6006CC605FE4922@AS1PR01MB9465.eurprd01.prod.exchangelabs.com> (raw)
In-Reply-To: <AS1PR01MB946510286FBF2497A6F03E83E4922@AS1PR01MB9465.eurprd01.prod.exchangelabs.com>

It may happen that the inline entry point is not the
start address of the first sub-range of an inline
function.

But the PC for a breakpoint on an inlined subroutine
is always the start address of the first sub-range.

This patch moves the sub-range starting at the entry
point to the first position of the block list.

Therefore the breakpoint on an inlined function
changes in rare cases from the start address of
the first sub-range to the real entry point.

There should always be a subrange that starts at the
entry point, even if that is an empty sub-range.
---
 gdb/dwarf2/read.c                       | 12 +++++++
 gdb/testsuite/gdb.base/inline-entry.c   | 39 ++++++++++++++++++++++
 gdb/testsuite/gdb.base/inline-entry.exp | 43 +++++++++++++++++++++++++
 3 files changed, 94 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/inline-entry.c
 create mode 100644 gdb/testsuite/gdb.base/inline-entry.exp

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 769ca91facc..95155a2ee59 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -11276,6 +11276,14 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
       if (die->tag != DW_TAG_compile_unit)
 	ranges_offset += cu->gnu_ranges_base;
 
+      CORE_ADDR entry_pc = (CORE_ADDR) -1;
+      if (die->tag == DW_TAG_inlined_subroutine)
+	{
+	  attr = dwarf2_attr (die, DW_AT_entry_pc, cu);
+	  if (attr != nullptr && !attr->form_is_constant ())
+	    entry_pc = per_objfile->relocate (attr->as_address ());
+	}
+
       std::vector<blockrange> blockvec;
       dwarf2_ranges_process (ranges_offset, cu, die->tag,
 	[&] (unrelocated_addr start, unrelocated_addr end)
@@ -11285,6 +11293,10 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
 	  cu->get_builder ()->record_block_range (block, abs_start,
 						  abs_end - 1);
 	  blockvec.emplace_back (abs_start, abs_end);
+	  /* This ensures that blockvec[0] is the one that starts
+	     at entry_pc, see block::entry_pc.  */
+	  if (entry_pc == abs_start && blockvec.size () > 1)
+	    std::swap (blockvec[0], blockvec[blockvec.size () - 1]);
 	});
 
       block->set_ranges (make_blockranges (objfile, blockvec));
diff --git a/gdb/testsuite/gdb.base/inline-entry.c b/gdb/testsuite/gdb.base/inline-entry.c
new file mode 100644
index 00000000000..bc36d8f9483
--- /dev/null
+++ b/gdb/testsuite/gdb.base/inline-entry.c
@@ -0,0 +1,39 @@
+/* Copyright 2024 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/>.  */
+
+volatile int global = 0;
+
+__attribute__((noinline, noclone)) void
+foo (int arg)
+{
+  global += arg;
+}
+
+inline __attribute__((always_inline)) int
+bar (int val)
+{
+  if (__builtin_expect(global == val, 0))
+    return 1;
+  foo (1);
+  return 1;
+}
+
+int
+main (void)
+{
+  if ((__builtin_expect(global, 0) && bar (1)) || bar (2))
+    return 1;
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/inline-entry.exp b/gdb/testsuite/gdb.base/inline-entry.exp
new file mode 100644
index 00000000000..20e112f7269
--- /dev/null
+++ b/gdb/testsuite/gdb.base/inline-entry.exp
@@ -0,0 +1,43 @@
+# Copyright 2024 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/>.
+
+standard_testfile .c
+
+if { [test_compiler_info gcc*] && ![supports_statement_frontiers] } {
+    untested "this test needs gcc with statement frontiers"
+    return -1
+}
+
+global srcfile testfile
+
+set options {debug nowarnings optimize=-O2}
+if { [supports_statement_frontiers] } {
+    lappend options additional_flags=-gstatement-frontiers
+}
+
+if { [prepare_for_testing "failed to prepare" $binfile \
+      $srcfile $options] } {
+    return -1
+}
+
+if ![runto_main] {
+    return
+}
+
+gdb_test "break bar" ".*Breakpoint 2 at .*" "break at bar"
+gdb_test "break foo" ".*Breakpoint 3 at .*" "break at foo"
+gdb_test "continue" ".*Breakpoint .* bar .*" "continue to bar"
+gdb_test "continue" ".*Breakpoint .* foo .*" "continue to foo"
+gdb_test "continue" ".* exited .*" "continue to exit"
-- 
2.39.2


  reply	other threads:[~2024-09-02 14:57 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-02 14:55 [PATCH v5 0/3] Improve debugging of optimized code Bernd Edlinger
2024-09-02 14:57 ` Bernd Edlinger [this message]
2024-09-10 20:34   ` [PATCH v5 1/3] Fix handling of DW_AT_entry_pc of inlined subroutines Guinevere Larsen
2024-10-16 15:49   ` Andrew Burgess
2024-09-02 14:58 ` [PATCH v5 2/3] Introduce a new line table flag is_weak Bernd Edlinger
2024-09-13 16:04   ` Guinevere Larsen
2024-09-02 15:00 ` [PATCH v5 3/3] Fix range end handling of inlined subroutines Bernd Edlinger
2024-10-18 10:47   ` Andrew Burgess
2024-09-26 17:40 ` [PATCH v5 0/3] Improve debugging of optimized code Andrew Burgess

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=AS1PR01MB94659E4D9B3F4A6006CC605FE4922@AS1PR01MB9465.eurprd01.prod.exchangelabs.com \
    --to=bernd.edlinger@hotmail.de \
    --cc=aburgess@redhat.com \
    --cc=blarsen@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).