[RFC] Enable to set breakpoint on line which includes inlined function call

Message ID 001501d002dd$50f86b30$f2e94190$@arm.com
State New, archived
Headers

Commit Message

Terry Guo Nov. 18, 2014, 3:11 a.m. UTC
  Hi there,

This patch intends to enable setting breakpoint on source line that has
inlined function call as shown in below case:

$ ../install-x86-upstream/bin/gdb a.out
GNU gdb (GDB) 7.8.50.20141117-cvs
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...done.
(gdb) !cat -n g.c
     1  volatile int x;
     2
     3  static inline void foo(int f)
     4  {
     5    volatile int y;
     6    y = f;
     7  }
     8
     9  __attribute__( ( always_inline ) ) static inline void bar(int b)
    10  {
    11    volatile int y;
    12    y = b;
    13  }
    14
    15  int main(void) {
    16
    17      x= 42;
    18
    19      if (x)
    20        foo(16);
    21      else
    22        foo(18);
    23
    24      while (1)
    25        {
    26          bar(10);
    27        }
    28
    29      return 0 ;
    30  }
    31
(gdb) b g.c:20
No line 20 in file "g.c".
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb)

Please use recent gcc 5.0 to build the case. Command is "gcc -O2 -g g.c".

The idea is to find functions that are inlined at specified line number and
then set breakpoint at first inlined function instruction, when we couldn't
find an instruction for specified line number. Tested with GDB regression
test on x86_64, no regression. Any comments?

BR,
Terry
  

Patch

diff --git a/gdb/linespec.c b/gdb/linespec.c
index 5325702..6630267 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1968,6 +1968,56 @@  create_sals_line_offset (struct linespec_state *self,
       do_cleanups (cleanup);
     }
 
+  /* See if any function gets inlined at specified line number.
+     If yes, then find the first inlined instruction and set
+     breakpoint to this instruction.  */
+  if (values.nelts == 0)
+    {
+      struct symtab *elt;
+      int ix;
+      struct block *sblock = NULL;
+      symtab_ptr selt = NULL;
+      struct symtab_and_line sal;
+      struct symbol *sym;
+
+      for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt); ++ix)
+	{
+	  int i;
+	  struct block *block;
+	  gdb_assert (elt != NULL);
+
+	  for (i = FIRST_LOCAL_BLOCK;
+	       i < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (elt)); i++)
+	    {
+	      block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (elt), i);
+
+	      if (block->function && block->function->is_inlined
+		  && block->function->line == val.line
+		  && (sblock == NULL || block->startaddr < sblock->startaddr))
+		{
+		  sblock = block;
+		  selt = elt;
+		}
+
+	    }
+	}
+
+      if (sblock)
+	{
+	  init_sal (&sal);
+
+	  sal.pspace = SYMTAB_PSPACE (selt);
+	  sal.symtab = selt;
+	  sal.line = val.line;
+	  sal.pc = sblock->startaddr;
+
+	  sym = (sblock ? block_containing_function (sblock) : NULL);
+
+	  add_sal_to_sals (self, &values, &sal,
+			   sym ? SYMBOL_NATURAL_NAME (sym) : NULL, 0);
+	}
+    }
+
   if (values.nelts == 0)
     {
       if (ls->source_filename)