This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patchv2] Do not skip prologue for asm (.S) files
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: Doug Evans <dje at google dot com>
- Cc: gdb-patches <gdb-patches at sourceware dot org>, Sergio Durigan Junior <sergiodj at redhat dot com>
- Date: Fri, 26 Jun 2015 10:36:44 +0200
- Subject: Re: [patchv2] Do not skip prologue for asm (.S) files
- Authentication-results: sourceware.org; auth=none
- References: <047d7b5d4b7a98ad1505195daa4a at google dot com>
On Thu, 25 Jun 2015 22:42:48 +0200, Doug Evans wrote:
> Hmmm, so there's an undocumented requirement that minsym_found
> and find_function_start_sal work compatibly?
> [Which is actually not surprising if you know how linespecs and
> breakpoints: we find all the matching minsyms and fullsyms
> and then throw away the duplicates. But if these two functions
> behave differently then the search for duplicates fails. At least
> I'm guessing that's what happened here.]
Yes:
# (gdb) file /root/jkratoch/redhat/gdb-clean/gdb/testsuite/gdb.base/breako2
# Reading symbols from /root/jkratoch/redhat/gdb-clean/gdb/testsuite/gdb.base/breako2...done.
# (gdb) break main
#-Breakpoint 1 at 0x10000644: file ./gdb.base/break.c, line 43.
#-(gdb) PASS: gdb.base/break.exp: breakpoint function, optimized file
#+Breakpoint 1 at 0x10000640: main. (2 locations)
#### Num Type Disp Enb Address What
#### 1 breakpoint keep y <MULTIPLE>
#### 1.1 y 0x0000000010000640 in main at ./gdb.base/break.c:42
#### 1.2 y 0x0000000010000644 in main at ./gdb.base/break.c:43
#+(gdb) FAIL: gdb.base/break.exp: breakpoint function, optimized file
# break marker4
# Breakpoint 2 at 0x10000aa0: file ./gdb.base/break1.c, line 59.
# (gdb) PASS: gdb.base/break.exp: breakpoint small function, optimized file
#[...]
# Continuing.
#-720
#-Breakpoint 2, marker4 (d=177601976) at ./gdb.base/break1.c:59
#-59 void marker4 (long d) { values[0].a_field = d; } /* set breakpoint 14 here */
#-(gdb) PASS: gdb.base/break.exp: run until breakpoint set at small function, optimized file (line bp_location14)
#+Breakpoint 1, main (argc=1, argv=0x3fffffffec48, envp=0x3fffffffec58) at ./gdb.base/break.c:43
#+43 if (argc == 12345) { /* an unlikely value < 2^16, in case uninited */ /* set breakpoint 6 here */
#+(gdb) FAIL: gdb.base/break.exp: run until breakpoint set at small function, optimized file
> Can you do that, plus add a comment to both minsym_found
> and find_function_start_sal stating that we rely on them
> working compatibly.
Done. Providing for review the final patch given all the changes.
Thanks,
Jan
gdb/ChangeLog
2015-06-26 Jan Kratochvil <jan.kratochvil@redhat.com>
* linespec.c (minsym_found): Reset sal.PC for COMPUNIT_LOCATIONS_VALID
and language_asm..
* symtab.c (find_function_start_sal): Likewise.
gdb/testsuite/ChangeLog
2015-06-20 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.arch/amd64-prologue-skip.S: New file.
* gdb.arch/amd64-prologue-skip.exp: New file.
diff --git a/gdb/linespec.c b/gdb/linespec.c
index d2089b5..65155d9 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -3432,7 +3432,9 @@ collect_symbols (struct symbol *sym, void *data)
}
/* We've found a minimal symbol MSYMBOL in OBJFILE to associate with our
- linespec; return the SAL in RESULT. */
+ linespec; return the SAL in RESULT. This function should return SALs
+ matching those from find_function_start_sal, otherwise false
+ multiple-locations breakpoints could be placed. */
static void
minsym_found (struct linespec_state *self, struct objfile *objfile,
@@ -3454,7 +3456,23 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
sal = find_pc_sect_line (pc, NULL, 0);
if (self->funfirstline)
- skip_prologue_sal (&sal);
+ {
+ if (sal.symtab != NULL
+ && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
+ || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
+ {
+ /* If gdbarch_convert_from_func_ptr_addr does not apply then
+ sal.SECTION, sal.LINE&co. will stay correct from above.
+ If gdbarch_convert_from_func_ptr_addr applies then
+ sal.SECTION is cleared from above and sal.LINE&co. will
+ stay correct from the last find_pc_sect_line above. */
+ sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
+ sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc,
+ ¤t_target);
+ }
+ else
+ skip_prologue_sal (&sal);
+ }
if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc))
add_sal_to_sals (self, result, &sal, MSYMBOL_NATURAL_NAME (msymbol), 0);
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 6693930..2b6af6c 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3605,7 +3605,9 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
/* Given a function symbol SYM, find the symtab and line for the start
of the function.
If the argument FUNFIRSTLINE is nonzero, we want the first line
- of real code inside the function. */
+ of real code inside the function.
+ This function should return SALs matching those from minsym_found,
+ otherwise false multiple-locations breakpoints could be placed. */
struct symtab_and_line
find_function_start_sal (struct symbol *sym, int funfirstline)
@@ -3617,6 +3619,14 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym);
sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), section, 0);
+ if (funfirstline && sal.symtab != NULL
+ && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
+ || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
+ {
+ sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ return sal;
+ }
+
/* We always should have a line for the function start address.
If we don't, something is odd. Create a plain SAL refering
just the PC and hope that skip_prologue_sal (if requested)
diff --git a/gdb/testsuite/gdb.arch/amd64-prologue-skip.S b/gdb/testsuite/gdb.arch/amd64-prologue-skip.S
new file mode 100644
index 0000000..66b806a
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-prologue-skip.S
@@ -0,0 +1,28 @@
+/* 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/>. */
+
+ .text
+/*0*/ hlt
+pushrbp: .globl pushrbp
+#define PUSHRBP push %rbp; mov %rsp, %rbp; nop
+/*1*/ PUSHRBP
+/*6*/ hlt
+
+/*7*/ hlt
+#define MINSYM nop; .globl minsym; minsym: nop
+/*8*/ MINSYM
+/*a*/ hlt
diff --git a/gdb/testsuite/gdb.arch/amd64-prologue-skip.exp b/gdb/testsuite/gdb.arch/amd64-prologue-skip.exp
new file mode 100644
index 0000000..015cd69
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-prologue-skip.exp
@@ -0,0 +1,35 @@
+# Copyright 2010-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/>.
+
+standard_testfile .S
+set binfile ${binfile}.o
+
+if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
+ verbose "Skipping ${testfile}."
+ return
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {debug}] != "" } {
+ untested ${testfile}
+ return
+}
+
+clean_restart ${binfile}
+
+gdb_test "break *pushrbp" " at 0x1: file .*"
+gdb_test "break pushrbp" " at 0x1: file .*"
+
+gdb_test "break *minsym" " at 0x9: file .*"
+gdb_test "break minsym" " at 0x9: file .*"