Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA] Allow setting breakpoints on inline functions (PR 10738)
@ 2011-11-29 15:02 Gary Benson
  2011-11-30 17:07 ` Tom Tromey
  2011-11-30 20:19 ` Jan Kratochvil
  0 siblings, 2 replies; 6+ messages in thread
From: Gary Benson @ 2011-11-29 15:02 UTC (permalink / raw)
  To: gdb-patches

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

Hi all,

This patch, which applies on top of Tom's ambiguous linespec work,
allows you to set breakpoints on inlined functions.  Although it
can't be committed until Tom's stuff goes in, I'm posting it for
feedback now.

I'm particularly interested in how this affects users of languages
other than C.  I'm also interested in feedback about the tests I've
written, since this is the first time I've worked on the testsuite.

Thanks,
Gary

-- 
http://gbenson.net/

[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 8831 bytes --]

2011-11-29  Gary Benson  <gbenson@redhat.com>

	PR breakpoints/10738
	* dwarf2read.c (struct partial_die_info): New member
	may_be_inlined.
	(read_partial_die): Set may_be_inlined where appropriate.
	(add_partial_subprogram): Add partial symbols for partial
	DIEs that may be inlined.
	(new_symbol_full): Add inlined subroutines to the static
	symbol table.

2011-11-29  Gary Benson  <gbenson@redhat.com>

	PR breakpoints/10738
	* gdb.opt/inline-break.exp: New file.
	* gdb.opt/inline-break.c: Likewise.

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 145c8d0..ee89286 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -578,6 +578,7 @@ struct partial_die_info
     unsigned int has_type : 1;
     unsigned int has_specification : 1;
     unsigned int has_pc_info : 1;
+    unsigned int may_be_inlined : 1;
 
     /* Flag set if the SCOPE field of this structure has been
        computed.  */
@@ -4285,6 +4286,10 @@ add_partial_subprogram (struct partial_die_info *pdi,
 				 pdi->highpc - 1 + baseaddr,
 				 cu->per_cu->v.psymtab);
 	    }
+        }
+
+      if (pdi->has_pc_info || (!pdi->is_external && pdi->may_be_inlined))
+	{
           if (!pdi->is_declaration)
 	    /* Ignore subprogram DIEs that do not have a name, they are
 	       illegal.  Do not emit a complaint at this point, we will
@@ -9925,6 +9930,11 @@ read_partial_die (struct partial_die_info *part_die,
 	      language_of_main = language_fortran;
 	    }
 	  break;
+	case DW_AT_inline:
+	  if (DW_UNSND (&attr) == DW_INL_inlined
+	      || DW_UNSND (&attr) == DW_INL_declared_inlined)
+	    part_die->may_be_inlined = 1;
+	  break;
 	default:
 	  break;
 	}
@@ -11800,8 +11810,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	     finish_block.  */
 	  SYMBOL_CLASS (sym) = LOC_BLOCK;
 	  SYMBOL_INLINED (sym) = 1;
-	  /* Do not add the symbol to any lists.  It will be found via
-	     BLOCK_FUNCTION from the blockvector.  */
+	  list_to_add = &file_symbols;
 	  break;
 	case DW_TAG_template_value_param:
 	  suppress_add = 1;
diff --git a/gdb/testsuite/gdb.opt/inline-break.c b/gdb/testsuite/gdb.opt/inline-break.c
new file mode 100644
index 0000000..7e1807f
--- /dev/null
+++ b/gdb/testsuite/gdb.opt/inline-break.c
@@ -0,0 +1,154 @@
+/* Copyright (C) 2011 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/>.  */
+
+#ifdef __GNUC__
+#define ATTR __attribute__((always_inline))
+#else
+#define ATTR
+#endif
+
+/* A static inlined function that is called once.  */
+
+static inline ATTR int
+func1 (int x)
+{
+  return x * 23;
+}
+
+/* A non-static inlined function that is called once.  */
+
+inline ATTR int
+func2 (int x)
+{
+  return x * 17;
+}
+
+/* A static inlined function that calls another static inlined
+   function.  */
+
+static inline ATTR int
+func3b (int x)
+{
+  return x < 14 ? 1 : 2;
+}
+
+static inline ATTR int
+func3a (int x)
+{
+  return func3b (x * 23);
+}
+
+/* A non-static inlined function that calls a static inlined
+   function.  */
+
+static inline ATTR int
+func4b (int x)
+{
+  return x < 13 ? 1 : 2;
+}
+
+inline ATTR int
+func4a (int x)
+{
+  return func4b (x * 17);
+}
+
+/* A static inlined function that calls a non-static inlined
+   function.  */
+
+inline ATTR int
+func5b (int x)
+{
+  return x < 12 ? 1 : 2;
+}
+
+static inline ATTR int
+func5a (int x)
+{
+  return func5b (x * 23);
+}
+
+/* A non-static inlined function that calls another non-static inlined
+   function.  */
+
+inline ATTR int
+func6b (int x)
+{
+  return x < 14 ? 3 : 2;
+}
+
+inline ATTR int
+func6a (int x)
+{
+  return func6b (x * 17);
+}
+
+/* A static inlined function that is called more than once.  */
+
+static inline ATTR int
+func7b (int x)
+{
+  return x < 23 ? 1 : 4;
+}
+
+static inline ATTR int
+func7a (int x)
+{
+  return func7b (x * 29);
+}
+
+/* A non-static inlined function that is called more than once.  */
+
+inline ATTR int
+func8b (int x)
+{
+  return x < 7 ? 11 : 9;
+}
+
+static inline ATTR int
+func8a (int x)
+{
+  return func8b (x * 31);
+}
+
+/* Entry point.  */
+
+int
+main (int argc, char *argv[])
+{
+  /* Declaring x as volatile here prevents GCC from combining calls.
+     If GCC is allowed to combine calls then some of them end up with
+     no instructions at all, so there is no specific address for GDB
+     to set a breakpoint at.  */
+  volatile int x = argc;
+
+  x = func1 (x);
+
+  x = func2 (x);
+
+  x = func3a (x);
+
+  x = func4a (x);
+
+  x = func5a (x);
+
+  x = func6a (x);
+
+  x = func7a (x) + func7b (x);
+
+  x = func8a (x) + func8b (x);
+
+  return x;
+}
diff --git a/gdb/testsuite/gdb.opt/inline-break.exp b/gdb/testsuite/gdb.opt/inline-break.exp
new file mode 100644
index 0000000..63d1fad
--- /dev/null
+++ b/gdb/testsuite/gdb.opt/inline-break.exp
@@ -0,0 +1,91 @@
+# Copyright 2011 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 "inline-break"
+
+if { [prepare_for_testing $testfile.exp $testfile $testfile.c \
+          {debug optimize=-O2 additional_flags=-Winline}] } {
+    return -1
+}
+
+#
+# func1 is a static inlined function that is called once.
+# The result should be a single-location breakpoint.
+#
+gdb_test "break func1" \
+    "Breakpoint.*at.* file .*$testfile\.c, line.*"
+
+#
+# func2 is a non-static inlined function that is called once.
+# The result should be a breakpoint with two locations: the
+# out-of-line function and the single inlined instance.
+#
+gdb_test "break func2" \
+    "Breakpoint.*at.*func2.*(2 locations).*"
+
+#
+# func3b is a static inlined function that is called once from
+# within another static inlined function.  The result should be
+# a single-location breakpoint.
+#
+gdb_test "break func3b" \
+    "Breakpoint.*at.* file .*$testfile\.c, line.*"
+
+#
+# func4b is a static inlined function that is called once from
+# within a non-static inlined function.  The result should be
+# a breakpoint with two locations: the inlined instance within
+# the inlined call to func4a in main, and the inlined instance
+# within the out-of-line func4a.
+#
+gdb_test "break func4b" \
+    "Breakpoint.*at.*func4b.*(2 locations).*"
+
+#
+# func5b is a non-static inlined function that is called once
+# from within a static inlined function.  The result should be a
+# breakpoint with two locations: the out-of-line function and the
+# inlined instance within the inlined call to func5a in main.
+#
+gdb_test "break func5b" \
+    "Breakpoint.*at.*func5b.*(2 locations).*"
+#
+# func6b is a non-static inlined function that is called once from
+# within another non-static inlined function.  The result should be
+# a breakpoint with three locations: the out-of-line function, the
+# inlined instance within the out-of-line func6a, and the inlined
+# instance within the inlined call to func6a in main,
+#
+gdb_test "break func6b" \
+    "Breakpoint.*at.*func6b.*(3 locations).*"
+
+#
+# func7b is a static inlined function that is called twice: once from
+# func7a, and once from main.  The result should be a breakpoint with
+# two locations: the inlined instance within the inlined instance of
+# func7a, and the inlined instance within main.
+#
+gdb_test "break func7b" \
+    "Breakpoint.*at.*func7b.*(2 locations).*"
+
+#
+# func8b is a non-static inlined function that is called twice: once
+# func8a, and once from main.  The result should be a breakpoint with
+# three locations: the out-of-line function, the inlined instance
+# within the inlined instance of func7a, and the inlined instance
+# within main.
+#
+gdb_test "break func8b" \
+    "Breakpoint.*at.*func8b.*(3 locations).*"

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-12-02 13:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-29 15:02 [RFA] Allow setting breakpoints on inline functions (PR 10738) Gary Benson
2011-11-30 17:07 ` Tom Tromey
2011-12-02 13:48   ` Gary Benson
2011-11-30 20:19 ` Jan Kratochvil
2011-12-01 13:41   ` Gary Benson
2011-12-01 18:53     ` Jan Kratochvil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox