This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit] Fix a prologue skipping bug


Vladimir has been doing some work on support for breakpoints in
constructors recently (I hope we'll have this ready to post by soon
after GDB 6.7 branches).  In the process we discovered a strange bug:
setting a breakpoint on 'Derived::Derived()' and on Derived::Derived
picked different locations, a few instructions apart.

There are a small handful of places in GDB which call
gdbarch_skip_prologue.  All but one of them then advance to the end of
the current line if there is debug info.  In minsym_found, I bet that
someone assumed line numbers would not be available if we got there
via a minimal symbol; that's normally true, but there are a few
exceptions.  The testcase shows another such exception.  So I applied
the straightforward fix, to use line number information if (and only
if) it is available.

I tested this on x86_64-linux and committed it.

-- 
Daniel Jacobowitz
CodeSourcery

2007-07-31  Daniel Jacobowitz  <dan@codesourcery.com>

	* linespec.c (minsym_found): Advance to the next line if possible.

2007-07-31  Daniel Jacobowitz  <dan@codesourcery.com>

	* gdb.base/prologue.c, gdb.base/prologue.exp: New.
	* lib/gdb.exp (gdb_breakpoint): Handle "temporary".

Index: linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.69
diff -u -p -r1.69 linespec.c
--- linespec.c	18 Jun 2007 18:23:08 -0000	1.69
+++ linespec.c	31 Jul 2007 18:53:39 -0000
@@ -1833,11 +1833,27 @@ minsym_found (int funfirstline, struct m
   values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
   if (funfirstline)
     {
+      struct symtab_and_line sal;
+
       values.sals[0].pc
 	+= gdbarch_deprecated_function_start_offset (current_gdbarch);
       values.sals[0].pc = gdbarch_skip_prologue
 			    (current_gdbarch, values.sals[0].pc);
+
+      sal = find_pc_sect_line (values.sals[0].pc, values.sals[0].section, 0);
+
+      /* Check if SKIP_PROLOGUE left us in mid-line, and the next
+	 line is still part of the same function.  If there is no
+	 line information here, sal.pc will be the passed in PC.  */
+      if (sal.pc != values.sals[0].pc
+	  && (lookup_minimal_symbol_by_pc_section (values.sals[0].pc,
+						   values.sals[0].section)
+	      == lookup_minimal_symbol_by_pc_section (sal.end,
+						      values.sals[0].section)))
+	/* Recalculate the line number (might not be N+1).  */
+	values.sals[0] = find_pc_sect_line (sal.end, values.sals[0].section, 0);
     }
+
   values.nelts = 1;
   return values;
 }
Index: testsuite/gdb.base/prologue.c
===================================================================
RCS file: testsuite/gdb.base/prologue.c
diff -N testsuite/gdb.base/prologue.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.base/prologue.c	31 Jul 2007 18:53:39 -0000
@@ -0,0 +1,39 @@
+/* This test is part of GDB, the GNU debugger.
+
+   Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+   */
+
+int leaf (void)
+{
+  return 1;
+}
+
+int marker (int val)
+{
+  leaf ();
+  return leaf () * val;
+}
+
+int other (int val) __attribute__((alias("marker")));
+
+int main(void)
+{
+  marker (0);
+  marker (0);
+
+  return 0;
+}
Index: testsuite/gdb.base/prologue.exp
===================================================================
RCS file: testsuite/gdb.base/prologue.exp
diff -N testsuite/gdb.base/prologue.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.base/prologue.exp	31 Jul 2007 18:53:39 -0000
@@ -0,0 +1,68 @@
+# Test for prologue skipping in minimal symbols with line info.
+# Copyright 2007 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "prologue"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     untested prologue.exp
+     return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+proc find_breakpoint_pc { sym } {
+    global decimal hex gdb_prompt
+
+    if { [gdb_breakpoint $sym temporary] } {
+	pass "setting breakpoint at $sym"
+    }
+
+    gdb_test "continue" "marker \\(.*\\) at.*" "continue to $sym"
+
+    set pc 0
+    set msg "reading \$pc: $sym"
+    gdb_test_multiple "print/x \$pc" $msg {
+	-re "\\\$$decimal = ($hex)\r\n$gdb_prompt $" {
+	    set pc $expect_out(1,string)
+	    pass $msg
+	}
+    }
+
+    return $pc
+}
+
+# GDB would skip the prologue differently when given a symbol with
+# debug info than when given a minimal symbol from the symbol table.
+# Make sure this is fixed.
+
+set pc1 [find_breakpoint_pc "marker"]
+
+set pc2 [find_breakpoint_pc "other"]
+
+gdb_test "print $pc1 == $pc2" "\\\$$decimal = 1" "same pc from minimal symbol"
Index: testsuite/lib/gdb.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/gdb.exp,v
retrieving revision 1.83
diff -u -p -r1.83 gdb.exp
--- testsuite/lib/gdb.exp	2 Jul 2007 21:29:28 -0000	1.83
+++ testsuite/lib/gdb.exp	31 Jul 2007 18:53:39 -0000
@@ -324,7 +324,7 @@ proc gdb_start_cmd {args} {
 }
 
 # Set a breakpoint at FUNCTION.  If there is an additional argument it is
-# a list of options; the only currently supported option is allow-pending.
+# a list of options; the supported options are allow-pending and temporary.
 
 proc gdb_breakpoint { function args } {
     global gdb_prompt
@@ -335,7 +335,12 @@ proc gdb_breakpoint { function args } {
 	set pending_response y
     }
 
-    send_gdb "break $function\n"
+    set break_command "break"
+    if {[lsearch -exact [lindex $args 0] temporary] != -1} {
+	set break_command "tbreak"
+    }
+
+    send_gdb "$break_command $function\n"
     # The first two regexps are what we get with -g, the third is without -g.
     gdb_expect 30 {
 	-re "Breakpoint \[0-9\]* at .*: file .*, line $decimal.\r\n$gdb_prompt $" {}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]