f314eb3eb5
Fix -O2 -g breakpoints internal error + prologue skipping (BZ 612253). Fix case insensitive symbols for Fortran by iFort (BZ 645773). Fix physname-related CU expansion issue for C++ (PR 12708). Fix Python access to inlined frames (BZ 694824).
831 lines
27 KiB
Diff
831 lines
27 KiB
Diff
http://sourceware.org/ml/gdb-patches/2011-04/msg00229.html
|
|
Subject: [rfc, 7.3?] -O2 -g breakpoints internal error + prologue skipping
|
|
|
|
[ Backported. ]
|
|
|
|
Hi,
|
|
|
|
obsoletes my:
|
|
[patch] Fix internal error on some -O2 -g breakpoints
|
|
http://sourceware.org/ml/gdb-patches/2010-07/msg00533.html
|
|
and IMO also Paul's:
|
|
[patch] Fix for PR gdb/12573
|
|
http://sourceware.org/ml/gdb-patches/2011-03/msg00883.html
|
|
it is an improvement of:
|
|
[patch] Do not skip prologue for -O2 -g with GCC VTA Re: [patch] Fix for PR gdb/12573
|
|
http://sourceware.org/ml/gdb-patches/2011-03/msg01129.html
|
|
|
|
Just the removal of gdb_assert may place the breakpoints on -O2 -g code too
|
|
late. IMO on `(gdb) break Bar::Bar' no real inferior modification should
|
|
happen while with the Paul's reproducer in the PR the `free(malloc(1));' line
|
|
is already executed when GDB stops. This over-execution is tested in the
|
|
attached artificial reproducer by the testcase "no statement got executed".
|
|
|
|
There are several issues of this patch:
|
|
|
|
#1 The two-pass complicated execution in skip_prologue_sal currently has no
|
|
effect as the functionality depending on it does not work now. But that is
|
|
a separate new Bug and the two passes will be needed after its fix:
|
|
regression by physname: PE32 prologue skip vs. static initializers
|
|
http://sourceware.org/bugzilla/show_bug.cgi?id=12680
|
|
|
|
#2 A conservative approach has been taken. The problematic prologue skipping
|
|
is disabled only if .debug_loc reference is found which proves -O2 (with -g).
|
|
This test is imperfect as there may exist optimized debug code not using
|
|
any location list and still facing inlining issues if handled as
|
|
unoptimized code. For a future better test see GCC PR other/32998.
|
|
GCC PR other/32998 = -frecord-gcc-switches issues, Status: NEW
|
|
The opposite option would be to keep the prologue skipping enabled only if
|
|
there is any DW_AT_location(DW_OP_fbreg(x)). I haven't tested this way, it
|
|
seems very intrusive to me. In practice I doubt there will be a real world
|
|
case of -O2 -g CU not referencing .debug_loc - such as if all its code accesses
|
|
only global variables and has no local variables. Just the testcase originally
|
|
was such a countercase CU. :-/ The GDB internal error is kept in place as it
|
|
still can happen in such case, this problem is not yet fully fixed.
|
|
|
|
#3 Whether a .debug_loc reference may be present with still invalid
|
|
DW_AT_location before prologue I do not know, it does not seem to happen for
|
|
GCC. There is currently no DW_AT_producer check. Even before VTA (Variable
|
|
Tracking Assignments, since FSF GCC 4.5, -O2 -g variables DW_AT_location
|
|
improvement) it seems to me the validity at function entry point worked well
|
|
enough.
|
|
|
|
#4 This whole problems appears only with involvement of inlined code, either
|
|
explicitly or implicitly. But GDB does not support inlined code breakpoints
|
|
well (PR breakpoints/10738, RH BZ#149125). When one plays with testing this
|
|
patch various suitable breakpoints are not placed but AFAIK all of them are in
|
|
the scope of the PR 10738.
|
|
|
|
#5 If function does not start is not on a line boundary the multi-location
|
|
breakpoints are already not found properly and everything fails. I do not
|
|
think it can ever happen in real world. Even for a singe-line code
|
|
void f (void) {} void g (void) {}
|
|
GCC places there multiple line markers - -O2 -g, duplicity is for prologues:
|
|
File name Line number Starting address
|
|
1.c 1 0
|
|
1.c 1 0
|
|
1.c 1 0x10
|
|
1.c 1 0x10
|
|
|
|
|
|
Whether this should go for 7.3 I am not sure. The simple removal of
|
|
gdb_assert looks nice, GDB does not crash. But GDB behaves wrong and `break
|
|
func' may not stop before a crash there at all etc.
|
|
|
|
No regressions on {x86_64,x86_64-m32,i686}-fedora15-linux-gnu.
|
|
|
|
I will to commit it without any review/discussion.
|
|
|
|
|
|
Thanks,
|
|
Jan
|
|
|
|
|
|
gdb/
|
|
2011-04-15 Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
|
|
* dwarf2read.c (struct dwarf2_cu): New field has_loclist.
|
|
(process_full_comp_unit): Set also symtab->locations_valid. Move the
|
|
symtab->language code.
|
|
(var_decode_location): Set cu->has_loclist.
|
|
* symtab.c (skip_prologue_sal): New variables saved_pc, force_skip and
|
|
skip. Intialize force_skip from locations_valid. Move the prologue
|
|
skipping code into two passes.
|
|
* symtab.h (struct symtab): Make the primary field a bitfield. New
|
|
field locations_valid.
|
|
|
|
gdb/testsuite/
|
|
2011-04-15 Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
|
|
* gdb.dwarf2/dw2-skip-prologue.S: New file.
|
|
* gdb.dwarf2/dw2-skip-prologue.c: New file.
|
|
* gdb.dwarf2/dw2-skip-prologue.exp: New file.
|
|
|
|
--- a/gdb/dwarf2read.c
|
|
+++ b/gdb/dwarf2read.c
|
|
@@ -396,6 +396,13 @@ struct dwarf2_cu
|
|
DIEs for namespaces, we don't need to try to infer them
|
|
from mangled names. */
|
|
unsigned int has_namespace_info : 1;
|
|
+
|
|
+ /* This CU references .debug_loc. See the symtab->locations_valid field.
|
|
+ This test is imperfect as there may exist optimized debug code not using
|
|
+ any location list and still facing inlining issues if handled as
|
|
+ unoptimized code. For a future better test see GCC PR other/32998. */
|
|
+
|
|
+ unsigned int has_loclist : 1;
|
|
};
|
|
|
|
/* Persistent data held for a compilation unit, even when not
|
|
@@ -4654,13 +4661,15 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
|
|
|
|
symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
|
|
|
|
- /* Set symtab language to language from DW_AT_language.
|
|
- If the compilation is from a C file generated by language preprocessors,
|
|
- do not set the language if it was already deduced by start_subfile. */
|
|
- if (symtab != NULL
|
|
- && !(cu->language == language_c && symtab->language != language_c))
|
|
+ if (symtab != NULL)
|
|
{
|
|
- symtab->language = cu->language;
|
|
+ /* Set symtab language to language from DW_AT_language. If the
|
|
+ compilation is from a C file generated by language preprocessors, do
|
|
+ not set the language if it was already deduced by start_subfile. */
|
|
+ if (!(cu->language == language_c && symtab->language != language_c))
|
|
+ symtab->language = cu->language;
|
|
+
|
|
+ symtab->locations_valid = cu->has_loclist;
|
|
}
|
|
|
|
if (dwarf2_per_objfile->using_index)
|
|
@@ -11221,6 +11230,9 @@ var_decode_location (struct attribute *a
|
|
|
|
SYMBOL_CLASS (sym) = LOC_COMPUTED;
|
|
dwarf2_symbol_mark_computed (attr, sym, cu);
|
|
+
|
|
+ if (SYMBOL_COMPUTED_OPS (sym) == &dwarf2_loclist_funcs)
|
|
+ cu->has_loclist = 1;
|
|
}
|
|
|
|
/* Given a pointer to a DWARF information entry, figure out if we need
|
|
--- a/gdb/symtab.c
|
|
+++ b/gdb/symtab.c
|
|
@@ -2454,12 +2454,13 @@ skip_prologue_sal (struct symtab_and_line *sal)
|
|
struct symbol *sym;
|
|
struct symtab_and_line start_sal;
|
|
struct cleanup *old_chain;
|
|
- CORE_ADDR pc;
|
|
+ CORE_ADDR pc, saved_pc;
|
|
struct obj_section *section;
|
|
const char *name;
|
|
struct objfile *objfile;
|
|
struct gdbarch *gdbarch;
|
|
struct block *b, *function_block;
|
|
+ int force_skip, skip;
|
|
|
|
/* Do not change the SAL is PC was specified explicitly. */
|
|
if (sal->explicit_pc)
|
|
@@ -2497,46 +2498,69 @@ skip_prologue_sal (struct symtab_and_line *sal)
|
|
|
|
gdbarch = get_objfile_arch (objfile);
|
|
|
|
- /* If the function is in an unmapped overlay, use its unmapped LMA address,
|
|
- so that gdbarch_skip_prologue has something unique to work on. */
|
|
- if (section_is_overlay (section) && !section_is_mapped (section))
|
|
- pc = overlay_unmapped_address (pc, section);
|
|
+ /* Process the prologue in two passes. In the first pass try to skip the
|
|
+ prologue (SKIP is true) and verify there is a real need for it (indicated
|
|
+ by FORCE_SKIP). If no such reason was found run a second pass where the
|
|
+ prologue is not skipped (SKIP is false). */
|
|
|
|
- /* Skip "first line" of function (which is actually its prologue). */
|
|
- pc += gdbarch_deprecated_function_start_offset (gdbarch);
|
|
- pc = gdbarch_skip_prologue (gdbarch, pc);
|
|
+ skip = 1;
|
|
+ force_skip = 1;
|
|
|
|
- /* For overlays, map pc back into its mapped VMA range. */
|
|
- pc = overlay_mapped_address (pc, section);
|
|
+ /* Be conservative - allow direct PC (without skipping prologue) only if we
|
|
+ have proven the CU (Compilation Unit) supports it. sal->SYMTAB does not
|
|
+ have to be set by the caller so we use SYM instead. */
|
|
+ if (sym && SYMBOL_SYMTAB (sym)->locations_valid)
|
|
+ force_skip = 0;
|
|
|
|
- /* Calculate line number. */
|
|
- start_sal = find_pc_sect_line (pc, section, 0);
|
|
-
|
|
- /* Check if gdbarch_skip_prologue left us in mid-line, and the next
|
|
- line is still part of the same function. */
|
|
- if (start_sal.pc != pc
|
|
- && (sym? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end
|
|
- && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
|
|
- : (lookup_minimal_symbol_by_pc_section (start_sal.end, section)
|
|
- == lookup_minimal_symbol_by_pc_section (pc, section))))
|
|
+ saved_pc = pc;
|
|
+ do
|
|
{
|
|
- /* First pc of next line */
|
|
- pc = start_sal.end;
|
|
- /* Recalculate the line number (might not be N+1). */
|
|
- start_sal = find_pc_sect_line (pc, section, 0);
|
|
- }
|
|
+ pc = saved_pc;
|
|
|
|
- /* On targets with executable formats that don't have a concept of
|
|
- constructors (ELF with .init has, PE doesn't), gcc emits a call
|
|
- to `__main' in `main' between the prologue and before user
|
|
- code. */
|
|
- if (gdbarch_skip_main_prologue_p (gdbarch)
|
|
- && name && strcmp (name, "main") == 0)
|
|
- {
|
|
- pc = gdbarch_skip_main_prologue (gdbarch, pc);
|
|
- /* Recalculate the line number (might not be N+1). */
|
|
+ /* If the function is in an unmapped overlay, use its unmapped LMA address,
|
|
+ so that gdbarch_skip_prologue has something unique to work on. */
|
|
+ if (section_is_overlay (section) && !section_is_mapped (section))
|
|
+ pc = overlay_unmapped_address (pc, section);
|
|
+
|
|
+ /* Skip "first line" of function (which is actually its prologue). */
|
|
+ pc += gdbarch_deprecated_function_start_offset (gdbarch);
|
|
+ if (skip)
|
|
+ pc = gdbarch_skip_prologue (gdbarch, pc);
|
|
+
|
|
+ /* For overlays, map pc back into its mapped VMA range. */
|
|
+ pc = overlay_mapped_address (pc, section);
|
|
+
|
|
+ /* Calculate line number. */
|
|
start_sal = find_pc_sect_line (pc, section, 0);
|
|
+
|
|
+ /* Check if gdbarch_skip_prologue left us in mid-line, and the next
|
|
+ line is still part of the same function. */
|
|
+ if (skip && start_sal.pc != pc
|
|
+ && (sym? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end
|
|
+ && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
|
|
+ : (lookup_minimal_symbol_by_pc_section (start_sal.end, section)
|
|
+ == lookup_minimal_symbol_by_pc_section (pc, section))))
|
|
+ {
|
|
+ /* First pc of next line */
|
|
+ pc = start_sal.end;
|
|
+ /* Recalculate the line number (might not be N+1). */
|
|
+ start_sal = find_pc_sect_line (pc, section, 0);
|
|
+ }
|
|
+
|
|
+ /* On targets with executable formats that don't have a concept of
|
|
+ constructors (ELF with .init has, PE doesn't), gcc emits a call
|
|
+ to `__main' in `main' between the prologue and before user
|
|
+ code. */
|
|
+ if (gdbarch_skip_main_prologue_p (gdbarch)
|
|
+ && name && strcmp (name, "main") == 0)
|
|
+ {
|
|
+ pc = gdbarch_skip_main_prologue (gdbarch, pc);
|
|
+ /* Recalculate the line number (might not be N+1). */
|
|
+ start_sal = find_pc_sect_line (pc, section, 0);
|
|
+ force_skip = 1;
|
|
+ }
|
|
}
|
|
+ while (!force_skip && skip--);
|
|
|
|
/* If we still don't have a valid source line, try to find the first
|
|
PC in the lineinfo table that belongs to the same function. This
|
|
@@ -2546,7 +2570,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
|
|
the case with the DJGPP target using "gcc -gcoff" when the
|
|
compiler inserted code after the prologue to make sure the stack
|
|
is aligned. */
|
|
- if (sym && start_sal.symtab == NULL)
|
|
+ if (!force_skip && sym && start_sal.symtab == NULL)
|
|
{
|
|
pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym));
|
|
/* Recalculate the line number. */
|
|
--- a/gdb/symtab.h
|
|
+++ b/gdb/symtab.h
|
|
@@ -767,7 +767,13 @@ struct symtab
|
|
should be designated the primary, so that the blockvector
|
|
is relocated exactly once by objfile_relocate. */
|
|
|
|
- int primary;
|
|
+ unsigned int primary : 1;
|
|
+
|
|
+ /* Symtab has been compiled with both optimizations and debug info so that
|
|
+ GDB may stop skipping prologues as variables locations are valid already
|
|
+ at function entry points. */
|
|
+
|
|
+ unsigned int locations_valid : 1;
|
|
|
|
/* The macro table for this symtab. Like the blockvector, this
|
|
may be shared between different symtabs --- and normally is for
|
|
--- /dev/null
|
|
+++ b/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.S
|
|
@@ -0,0 +1,391 @@
|
|
+/* This testcase is part of GDB, the GNU debugger.
|
|
+
|
|
+ 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/>. */
|
|
+
|
|
+ .section .debug_info
|
|
+.Lcu1_begin:
|
|
+ /* CU header */
|
|
+ .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
|
|
+.Lcu1_start:
|
|
+ .2byte 2 /* DWARF Version */
|
|
+ .4byte .Labbrev1_begin /* Offset into abbrev section */
|
|
+ .byte 4 /* Pointer size */
|
|
+
|
|
+ /* CU die */
|
|
+ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
|
|
+ .4byte .Lline1_begin /* DW_AT_stmt_list */
|
|
+ .4byte func_start /* DW_AT_low_pc */
|
|
+ .4byte func_end /* DW_AT_high_pc */
|
|
+ .ascii "main.c\0" /* DW_AT_name */
|
|
+ .ascii "GNU C 3.3.3\0" /* DW_AT_producer */
|
|
+ .byte 2 /* DW_AT_language (DW_LANG_C) */
|
|
+
|
|
+ .uleb128 2 /* Abbrev: DW_TAG_subprogram */
|
|
+ .byte 1 /* DW_AT_external */
|
|
+ .ascii "func\0" /* DW_AT_name */
|
|
+ .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */
|
|
+ .4byte func_start /* DW_AT_low_pc */
|
|
+ .4byte func_end /* DW_AT_high_pc */
|
|
+
|
|
+/* GDB `has_loclist' detection of -O2 -g code needs to see a DW_AT_location
|
|
+ location list. There may exist -O2 -g CUs still not needing/using any such
|
|
+ location list - exactly like this CU. Make one up. */
|
|
+
|
|
+ .uleb128 0x7 /* (DIE (0x42) DW_TAG_formal_parameter) */
|
|
+ .ascii "param\0" /* DW_AT_name */
|
|
+ .long .Ltype_int - .Lcu1_begin /* DW_AT_type */
|
|
+ .long loclist /* DW_AT_location */
|
|
+
|
|
+ .uleb128 4 /* Abbrev: DW_TAG_inlined_subroutine */
|
|
+ .ascii "inlined\0" /* DW_AT_name */
|
|
+ .4byte func0 /* DW_AT_low_pc */
|
|
+ .4byte func1 /* DW_AT_high_pc */
|
|
+ .byte 3 /* DW_AT_inline (DW_INL_declared_inlined) */
|
|
+ .byte 1 /* DW_AT_call_file */
|
|
+ .byte 8 /* DW_AT_call_line */
|
|
+
|
|
+ .uleb128 4 /* Abbrev: DW_TAG_inlined_subroutine */
|
|
+ .ascii "inlined2\0" /* DW_AT_name */
|
|
+ .4byte func2 /* DW_AT_low_pc */
|
|
+ .4byte func3 /* DW_AT_high_pc */
|
|
+ .byte 3 /* DW_AT_inline (DW_INL_declared_inlined) */
|
|
+ .byte 1 /* DW_AT_call_file */
|
|
+ .byte 11 /* DW_AT_call_line */
|
|
+
|
|
+#ifdef INLINED
|
|
+ .uleb128 4 /* Abbrev: DW_TAG_inlined_subroutine */
|
|
+ .ascii "otherinline\0" /* DW_AT_name */
|
|
+ .4byte func3 /* DW_AT_low_pc */
|
|
+ .4byte func_end /* DW_AT_high_pc */
|
|
+ .byte 3 /* DW_AT_inline (DW_INL_declared_inlined) */
|
|
+ .byte 1 /* DW_AT_call_file */
|
|
+ .byte 9 /* DW_AT_call_line */
|
|
+#endif
|
|
+
|
|
+#ifdef LEXICAL
|
|
+ .uleb128 5 /* Abbrev: DW_TAG_lexical_block */
|
|
+ .4byte func3 /* DW_AT_low_pc */
|
|
+ .4byte func_end /* DW_AT_high_pc */
|
|
+
|
|
+ /* GDB would otherwise ignore the DW_TAG_lexical_block. */
|
|
+ .uleb128 6 /* Abbrev: DW_TAG_variable */
|
|
+ .ascii "lexicalvar\0" /* DW_AT_name */
|
|
+ .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */
|
|
+
|
|
+ .byte 0 /* End of children of DW_TAG_lexical_block */
|
|
+#endif
|
|
+
|
|
+ .byte 0 /* End of children of DW_TAG_subprogram */
|
|
+
|
|
+/* Simulate `fund' is also named `func' so that the function name matches and
|
|
+ fund's SAL is not discarded in expand_line_sal_maybe. */
|
|
+
|
|
+ .uleb128 2 /* Abbrev: DW_TAG_subprogram */
|
|
+ .byte 1 /* DW_AT_external */
|
|
+ .ascii "func\0" /* DW_AT_name */
|
|
+ .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */
|
|
+ .4byte fund_start /* DW_AT_low_pc */
|
|
+ .4byte fund_end /* DW_AT_high_pc */
|
|
+
|
|
+ .byte 0 /* End of children of DW_TAG_subprogram */
|
|
+
|
|
+.Ltype_int:
|
|
+ .uleb128 3 /* Abbrev: DW_TAG_base_type */
|
|
+ .ascii "int\0" /* DW_AT_name */
|
|
+ .byte 4 /* DW_AT_byte_size */
|
|
+ .byte 5 /* DW_AT_encoding */
|
|
+
|
|
+ .byte 0 /* End of children of CU */
|
|
+
|
|
+.Lcu1_end:
|
|
+
|
|
+ .section .debug_loc
|
|
+loclist:
|
|
+ /* Reset the location list base address first. */
|
|
+ .long -1, 0
|
|
+
|
|
+ .long func_start, func_end
|
|
+ .2byte 2f-1f
|
|
+1: .byte 0x50 /* DW_OP_reg0 */
|
|
+2:
|
|
+ /* Location list end. */
|
|
+ .long 0, 0
|
|
+
|
|
+/* Abbrev table */
|
|
+ .section .debug_abbrev
|
|
+.Labbrev1_begin:
|
|
+ .uleb128 1 /* Abbrev code */
|
|
+ .uleb128 0x11 /* DW_TAG_compile_unit */
|
|
+ .byte 1 /* has_children */
|
|
+ .uleb128 0x10 /* DW_AT_stmt_list */
|
|
+ .uleb128 0x6 /* DW_FORM_data4 */
|
|
+ .uleb128 0x11 /* DW_AT_low_pc */
|
|
+ .uleb128 0x1 /* DW_FORM_addr */
|
|
+ .uleb128 0x12 /* DW_AT_high_pc */
|
|
+ .uleb128 0x1 /* DW_FORM_addr */
|
|
+ .uleb128 0x3 /* DW_AT_name */
|
|
+ .uleb128 0x8 /* DW_FORM_string */
|
|
+ .uleb128 0x25 /* DW_AT_producer */
|
|
+ .uleb128 0x8 /* DW_FORM_string */
|
|
+ .uleb128 0x13 /* DW_AT_language */
|
|
+ .uleb128 0xb /* DW_FORM_data1 */
|
|
+ .byte 0x0 /* Terminator */
|
|
+ .byte 0x0 /* Terminator */
|
|
+
|
|
+ .uleb128 2 /* Abbrev code */
|
|
+ .uleb128 0x2e /* DW_TAG_subprogram */
|
|
+ .byte 1 /* has_children */
|
|
+ .uleb128 0x3f /* DW_AT_external */
|
|
+ .uleb128 0xc /* DW_FORM_flag */
|
|
+ .uleb128 0x3 /* DW_AT_name */
|
|
+ .uleb128 0x8 /* DW_FORM_string */
|
|
+ .uleb128 0x49 /* DW_AT_type */
|
|
+ .uleb128 0x13 /* DW_FORM_ref4 */
|
|
+ .uleb128 0x11 /* DW_AT_low_pc */
|
|
+ .uleb128 0x1 /* DW_FORM_addr */
|
|
+ .uleb128 0x12 /* DW_AT_high_pc */
|
|
+ .uleb128 0x1 /* DW_FORM_addr */
|
|
+ .byte 0x0 /* Terminator */
|
|
+ .byte 0x0 /* Terminator */
|
|
+
|
|
+ .uleb128 3 /* Abbrev code */
|
|
+ .uleb128 0x24 /* DW_TAG_base_type */
|
|
+ .byte 0 /* has_children */
|
|
+ .uleb128 0x3 /* DW_AT_name */
|
|
+ .uleb128 0x8 /* DW_FORM_string */
|
|
+ .uleb128 0xb /* DW_AT_byte_size */
|
|
+ .uleb128 0xb /* DW_FORM_data1 */
|
|
+ .uleb128 0x3e /* DW_AT_encoding */
|
|
+ .uleb128 0xb /* DW_FORM_data1 */
|
|
+ .byte 0x0 /* Terminator */
|
|
+ .byte 0x0 /* Terminator */
|
|
+
|
|
+ .uleb128 4 /* Abbrev code */
|
|
+ .uleb128 0x1d /* DW_TAG_inlined_subroutine */
|
|
+ .byte 0 /* has_children */
|
|
+ .uleb128 0x3 /* DW_AT_name */
|
|
+ .uleb128 0x8 /* DW_FORM_string */
|
|
+ .uleb128 0x11 /* DW_AT_low_pc */
|
|
+ .uleb128 0x1 /* DW_FORM_addr */
|
|
+ .uleb128 0x12 /* DW_AT_high_pc */
|
|
+ .uleb128 0x1 /* DW_FORM_addr */
|
|
+ .uleb128 0x20 /* DW_AT_inline */
|
|
+ .uleb128 0xb /* DW_FORM_data1 */
|
|
+ .uleb128 0x58 /* DW_AT_call_file */
|
|
+ .uleb128 0xb /* DW_FORM_data1 */
|
|
+ .uleb128 0x59 /* DW_AT_call_line */
|
|
+ .uleb128 0xb /* DW_FORM_data1 */
|
|
+ .byte 0x0 /* Terminator */
|
|
+ .byte 0x0 /* Terminator */
|
|
+
|
|
+ .uleb128 5 /* Abbrev code */
|
|
+ .uleb128 0x0b /* DW_TAG_lexical_block */
|
|
+ .byte 1 /* has_children */
|
|
+ .uleb128 0x11 /* DW_AT_low_pc */
|
|
+ .uleb128 0x1 /* DW_FORM_addr */
|
|
+ .uleb128 0x12 /* DW_AT_high_pc */
|
|
+ .uleb128 0x1 /* DW_FORM_addr */
|
|
+ .byte 0x0 /* Terminator */
|
|
+ .byte 0x0 /* Terminator */
|
|
+
|
|
+ .uleb128 6 /* Abbrev code */
|
|
+ .uleb128 0x34 /* DW_TAG_variable */
|
|
+ .byte 0 /* has_children */
|
|
+ .uleb128 0x3 /* DW_AT_name */
|
|
+ .uleb128 0x8 /* DW_FORM_string */
|
|
+ .uleb128 0x49 /* DW_AT_type */
|
|
+ .uleb128 0x13 /* DW_FORM_ref4 */
|
|
+ .byte 0x0 /* Terminator */
|
|
+ .byte 0x0 /* Terminator */
|
|
+
|
|
+ .uleb128 0x7 /* (abbrev code) */
|
|
+ .uleb128 0x5 /* (TAG: DW_TAG_formal_parameter) */
|
|
+ .byte 0x0 /* DW_children_no */
|
|
+ .uleb128 0x3 /* DW_AT_name */
|
|
+ .uleb128 0x8 /* DW_FORM_string */
|
|
+ .uleb128 0x49 /* (DW_AT_type) */
|
|
+ .uleb128 0x13 /* (DW_FORM_ref4) */
|
|
+ .uleb128 0x02 /* (DW_AT_location) */
|
|
+ .uleb128 0x06 /* (DW_FORM_data4) */
|
|
+ .byte 0x0
|
|
+ .byte 0x0
|
|
+
|
|
+ .byte 0x0 /* Terminator */
|
|
+ .byte 0x0 /* Terminator */
|
|
+
|
|
+/* Line table */
|
|
+ .section .debug_line
|
|
+.Lline1_begin:
|
|
+ .4byte .Lline1_end - .Lline1_start /* Initial length */
|
|
+.Lline1_start:
|
|
+ .2byte 2 /* Version */
|
|
+ .4byte .Lline1_lines - .Lline1_hdr /* header_length */
|
|
+.Lline1_hdr:
|
|
+ .byte 1 /* Minimum insn length */
|
|
+ .byte 1 /* default_is_stmt */
|
|
+ .byte 1 /* line_base */
|
|
+ .byte 1 /* line_range */
|
|
+ .byte 0x10 /* opcode_base */
|
|
+
|
|
+ /* Standard lengths */
|
|
+ .byte 0
|
|
+ .byte 1
|
|
+ .byte 1
|
|
+ .byte 1
|
|
+ .byte 1
|
|
+ .byte 0
|
|
+ .byte 0
|
|
+ .byte 0
|
|
+ .byte 1
|
|
+ .byte 0
|
|
+ .byte 0
|
|
+ .byte 1
|
|
+ .byte 0
|
|
+ .byte 0
|
|
+ .byte 0
|
|
+
|
|
+ /* Include directories */
|
|
+ .byte 0
|
|
+
|
|
+ /* File names */
|
|
+ .ascii "main.c\0"
|
|
+ .uleb128 0
|
|
+ .uleb128 0
|
|
+ .uleb128 0
|
|
+
|
|
+ .ascii "other.c\0"
|
|
+ .uleb128 0
|
|
+ .uleb128 0
|
|
+ .uleb128 0
|
|
+
|
|
+ .byte 0
|
|
+
|
|
+.Lline1_lines:
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte func_start
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 4 /* ... to 5 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte func0
|
|
+ .byte 4 /* DW_LNS_set_file */
|
|
+ .uleb128 2
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 -4 /* ... to 1 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte func1
|
|
+ .byte 4 /* DW_LNS_set_file */
|
|
+ .uleb128 1
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 8 /* ... to 9 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte func2
|
|
+ .byte 4 /* DW_LNS_set_file */
|
|
+ .uleb128 2
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 -8 /* ... to 1 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte func3
|
|
+ .byte 4 /* DW_LNS_set_file */
|
|
+ .uleb128 1
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 8 /* ... to 9 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte func_end
|
|
+
|
|
+/* Equivalent copy but renamed s/func/fund/. */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte fund_start
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 -4 /* ... to 5 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte fund0
|
|
+ .byte 4 /* DW_LNS_set_file */
|
|
+ .uleb128 2
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 -4 /* ... to 1 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte fund1
|
|
+ .byte 4 /* DW_LNS_set_file */
|
|
+ .uleb128 1
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 8 /* ... to 9 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte fund2
|
|
+ .byte 4 /* DW_LNS_set_file */
|
|
+ .uleb128 2
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 -8 /* ... to 1 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte fund3
|
|
+ .byte 4 /* DW_LNS_set_file */
|
|
+ .uleb128 1
|
|
+ .byte 3 /* DW_LNS_advance_line */
|
|
+ .sleb128 8 /* ... to 9 */
|
|
+ .byte 1 /* DW_LNS_copy */
|
|
+
|
|
+ .byte 0 /* DW_LNE_set_address */
|
|
+ .uleb128 5
|
|
+ .byte 2
|
|
+ .4byte fund_end
|
|
+
|
|
+/* Line numbering end. */
|
|
+
|
|
+ .byte 0 /* DW_LNE_end_of_sequence */
|
|
+ .uleb128 1
|
|
+ .byte 1
|
|
+
|
|
+.Lline1_end:
|
|
--- /dev/null
|
|
+++ b/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.c
|
|
@@ -0,0 +1,58 @@
|
|
+/* This testcase is part of GDB, the GNU debugger.
|
|
+
|
|
+ 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/>. */
|
|
+
|
|
+static volatile int v;
|
|
+
|
|
+asm ("func_start: .globl func_start\n");
|
|
+static int
|
|
+func (void)
|
|
+{
|
|
+ v++;
|
|
+asm ("func0: .globl func0\n");
|
|
+ v++;
|
|
+asm ("func1: .globl func1\n");
|
|
+ v++;
|
|
+asm ("func2: .globl func2\n");
|
|
+ v++;
|
|
+asm ("func3: .globl func3\n");
|
|
+ return v;
|
|
+}
|
|
+asm ("func_end: .globl func_end\n");
|
|
+
|
|
+/* Equivalent copy but renamed s/func/fund/. */
|
|
+
|
|
+asm ("fund_start: .globl fund_start\n");
|
|
+static int
|
|
+fund (void)
|
|
+{
|
|
+ v++;
|
|
+asm ("fund0: .globl fund0\n");
|
|
+ v++;
|
|
+asm ("fund1: .globl fund1\n");
|
|
+ v++;
|
|
+asm ("fund2: .globl fund2\n");
|
|
+ v++;
|
|
+asm ("fund3: .globl fund3\n");
|
|
+ return v;
|
|
+}
|
|
+asm ("fund_end: .globl fund_end\n");
|
|
+
|
|
+int
|
|
+main (void)
|
|
+{
|
|
+ return func () + fund ();
|
|
+}
|
|
--- /dev/null
|
|
+++ b/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp
|
|
@@ -0,0 +1,74 @@
|
|
+# 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/>.
|
|
+load_lib dwarf.exp
|
|
+
|
|
+# Test multiple location breakpoints vs. prologue analysis on -O2 -g code.
|
|
+# when the first statement of a function is an inlined function GDB could
|
|
+# crash. Map of this testcase:
|
|
+#
|
|
+# File name Line number Starting address
|
|
+# main.c 5 func_start
|
|
+# other.c 1 func0
|
|
+# `inlined' called at main.c line 8
|
|
+# main.c 9 func1
|
|
+# func1 = Breakpoint location 1
|
|
+# other.c 1 func2
|
|
+# `inlined2' called at main.c line 11
|
|
+# main.c 9 func3
|
|
+# func3 = Breakpoint location 2
|
|
+# `otherinline' called at main.c line 9
|
|
+# end of main func_end
|
|
+
|
|
+# This test can only be run on targets which support DWARF-2 and use gas.
|
|
+if {![dwarf2_support]} {
|
|
+ return 0
|
|
+}
|
|
+
|
|
+set testfile "dw2-skip-prologue"
|
|
+set executable ${testfile}
|
|
+set binfile ${objdir}/${subdir}/${executable}
|
|
+
|
|
+if {[build_executable ${testfile}.exp ${executable} "${testfile}.c ${testfile}.S" {additional_flags=-DINLINED}] == -1} {
|
|
+ return -1
|
|
+}
|
|
+
|
|
+# We need those symbols global to access them from the .S file.
|
|
+set test "strip stub symbols"
|
|
+set objcopy_program [transform objcopy]
|
|
+set result [catch "exec $objcopy_program \
|
|
+ -N func0 -N func1 -N func2 -N func3 -N func_start -N func_end \
|
|
+ -N fund0 -N fund1 -N fund2 -N fund3 -N fund -N fund_start \
|
|
+ ${binfile}" output]
|
|
+verbose "result is $result"
|
|
+verbose "output is $output"
|
|
+if {$result != 0} {
|
|
+ fail $test
|
|
+ return
|
|
+}
|
|
+pass $test
|
|
+
|
|
+clean_restart $executable
|
|
+
|
|
+if ![runto_main] {
|
|
+ return -1
|
|
+}
|
|
+
|
|
+gdb_breakpoint "func"
|
|
+gdb_continue_to_breakpoint "func"
|
|
+
|
|
+# Sanity check GDB has really found 2 locations
|
|
+gdb_test {info break $bpnum} "\r\n2\\.1\[ \t\]\[^\n\]*\r\n2\\.2\[ \t\]\[^\n\]*" "2 locations found"
|
|
+
|
|
+gdb_test "p v" " = 0" "no statement got executed"
|
|
|