mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-22 09:04:58 +00:00
PR 15231: import bare DW_TAG_lexical_block
Local variables in lambdas are not accessible https://sourceware.org/bugzilla/show_bug.cgi?id=15231 GDB: read_lexical_block_scope /* Ignore blocks with missing or invalid low and high pc attributes. */ [...] if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)) return; But sometimes there is: FAIL: gcc-5.3.1-6.fc23.x86_64 <2><92>: Abbrev Number: 11 (DW_TAG_lexical_block) <3><9c>: Abbrev Number: 13 (DW_TAG_structure_type) <9d> DW_AT_name : (indirect string, offset: 0x3c): <lambda()> [...] Where DW_TAG_lexical_block has no attributes. Such whole subtree is currently dropped by GDB while I think it should just import all its children DIEs. It even XFAIL->XPASSes gdb.ada/out_of_line_in_inlined.exp: commit 0fa7fe506c242b459c4c05d331e7c7d66fb52390 Author: Joel Brobecker <brobecker@adacore.com> out of line functions nested inside inline functions. So I have removed that xfail. gdb/ChangeLog 2016-05-30 Jan Kratochvil <jan.kratochvil@redhat.com> PR c++/15231 * dwarf2read.c (enum pc_bounds_kind): Add PC_BOUNDS_INVALID. (process_psymtab_comp_unit_reader, read_func_scope): Adjust callers. (read_lexical_block_scope): Import DIEs from bare DW_TAG_lexical_block. (read_call_site_scope): Adjust callers. (dwarf2_get_pc_bounds): Implement pc_bounds_invalid. (dwarf2_get_subprogram_pc_bounds, get_scope_pc_bounds): Adjust callers. gdb/testsuite/ChangeLog 2016-05-30 Jan Kratochvil <jan.kratochvil@redhat.com> PR c++/15231 * gdb.ada/out_of_line_in_inlined.exp: Remove xfails. * gdb.dwarf2/dw2-lexical-block-bare.exp: New file.
This commit is contained in:
parent
3a2b436ae9
commit
e385593eef
@ -1,3 +1,13 @@
|
||||
2016-05-30 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
PR c++/15231
|
||||
* dwarf2read.c (enum pc_bounds_kind): Add PC_BOUNDS_INVALID.
|
||||
(process_psymtab_comp_unit_reader, read_func_scope): Adjust callers.
|
||||
(read_lexical_block_scope): Import DIEs from bare DW_TAG_lexical_block.
|
||||
(read_call_site_scope): Adjust callers.
|
||||
(dwarf2_get_pc_bounds): Implement pc_bounds_invalid.
|
||||
(dwarf2_get_subprogram_pc_bounds, get_scope_pc_bounds): Adjust callers.
|
||||
|
||||
2016-05-30 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Code cleanup: dwarf2_get_pc_bounds: -1/0/+1 -> enum
|
||||
|
@ -1607,13 +1607,16 @@ static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
|
||||
struct dwarf2_cu *, struct partial_symtab *);
|
||||
|
||||
/* How dwarf2_get_pc_bounds constructed its *LOWPC and *HIGHPC return
|
||||
values. */
|
||||
values. Keep the items ordered with increasing constraints compliance. */
|
||||
enum pc_bounds_kind
|
||||
{
|
||||
/* No valid combination of DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges
|
||||
was found. */
|
||||
/* No attribute DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges was found. */
|
||||
PC_BOUNDS_NOT_PRESENT,
|
||||
|
||||
/* Some of the attributes DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges
|
||||
were present but they do not form a valid range of PC addresses. */
|
||||
PC_BOUNDS_INVALID,
|
||||
|
||||
/* Discontiguous range was found - that is DW_AT_ranges was found. */
|
||||
PC_BOUNDS_RANGES,
|
||||
|
||||
@ -6019,7 +6022,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
|
||||
first_die = load_partial_dies (reader, info_ptr, 1);
|
||||
|
||||
scan_partial_symbols (first_die, &lowpc, &highpc,
|
||||
cu_bounds_kind == PC_BOUNDS_NOT_PRESENT, cu);
|
||||
cu_bounds_kind <= PC_BOUNDS_INVALID, cu);
|
||||
|
||||
/* If we didn't find a lowpc, set it to highpc to avoid
|
||||
complaints from `maint check'. */
|
||||
@ -6028,7 +6031,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
|
||||
|
||||
/* If the compilation unit didn't have an explicit address range,
|
||||
then use the information extracted from its child dies. */
|
||||
if (cu_bounds_kind == PC_BOUNDS_NOT_PRESENT)
|
||||
if (cu_bounds_kind <= PC_BOUNDS_INVALID)
|
||||
{
|
||||
best_lowpc = lowpc;
|
||||
best_highpc = highpc;
|
||||
@ -11390,7 +11393,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||
|
||||
/* Ignore functions with missing or invalid low and high pc attributes. */
|
||||
if (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)
|
||||
== PC_BOUNDS_NOT_PRESENT)
|
||||
<= PC_BOUNDS_INVALID)
|
||||
{
|
||||
attr = dwarf2_attr (die, DW_AT_external, cu);
|
||||
if (!attr || !DW_UNSND (attr))
|
||||
@ -11552,9 +11555,20 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||
as multiple lexical blocks? Handling children in a sane way would
|
||||
be nasty. Might be easier to properly extend generic blocks to
|
||||
describe ranges. */
|
||||
if (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)
|
||||
== PC_BOUNDS_NOT_PRESENT)
|
||||
return;
|
||||
switch (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
|
||||
{
|
||||
case PC_BOUNDS_NOT_PRESENT:
|
||||
/* DW_TAG_lexical_block has no attributes, process its children as if
|
||||
there was no wrapping by that DW_TAG_lexical_block.
|
||||
GCC does no longer produces such DWARF since GCC r224161. */
|
||||
for (child_die = die->child;
|
||||
child_die != NULL && child_die->tag;
|
||||
child_die = sibling_die (child_die))
|
||||
process_die (child_die, cu);
|
||||
return;
|
||||
case PC_BOUNDS_INVALID:
|
||||
return;
|
||||
}
|
||||
lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
|
||||
highpc = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
|
||||
|
||||
@ -11764,7 +11778,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||
|
||||
/* DW_AT_entry_pc should be preferred. */
|
||||
if (dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL)
|
||||
== PC_BOUNDS_NOT_PRESENT)
|
||||
<= PC_BOUNDS_INVALID)
|
||||
complaint (&symfile_complaints,
|
||||
_("DW_AT_GNU_call_site_target target DIE has invalid "
|
||||
"low pc, for referencing DIE 0x%x [in module %s]"),
|
||||
@ -12041,7 +12055,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
|
||||
|
||||
/* Get low and high pc attributes from a die. See enum pc_bounds_kind
|
||||
definition for the return value. *LOWPC and *HIGHPC are set iff
|
||||
PC_BOUNDS_NOT_PRESENT is not returned. */
|
||||
neither PC_BOUNDS_NOT_PRESENT nor PC_BOUNDS_INVALID are returned. */
|
||||
|
||||
static enum pc_bounds_kind
|
||||
dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
|
||||
@ -12052,7 +12066,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
|
||||
struct attribute *attr_high;
|
||||
CORE_ADDR low = 0;
|
||||
CORE_ADDR high = 0;
|
||||
enum pc_bounds_kind ret = PC_BOUNDS_NOT_PRESENT;
|
||||
enum pc_bounds_kind ret;
|
||||
|
||||
attr_high = dwarf2_attr (die, DW_AT_high_pc, cu);
|
||||
if (attr_high)
|
||||
@ -12067,7 +12081,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
|
||||
}
|
||||
else
|
||||
/* Found high w/o low attribute. */
|
||||
return PC_BOUNDS_NOT_PRESENT;
|
||||
return PC_BOUNDS_INVALID;
|
||||
|
||||
/* Found consecutive range of addresses. */
|
||||
ret = PC_BOUNDS_HIGH_LOW;
|
||||
@ -12089,15 +12103,17 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
|
||||
/* Value of the DW_AT_ranges attribute is the offset in the
|
||||
.debug_ranges section. */
|
||||
if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst))
|
||||
return PC_BOUNDS_NOT_PRESENT;
|
||||
return PC_BOUNDS_INVALID;
|
||||
/* Found discontinuous range of addresses. */
|
||||
ret = PC_BOUNDS_RANGES;
|
||||
}
|
||||
else
|
||||
return PC_BOUNDS_NOT_PRESENT;
|
||||
}
|
||||
|
||||
/* read_partial_die has also the strict LOW < HIGH requirement. */
|
||||
if (high <= low)
|
||||
return PC_BOUNDS_NOT_PRESENT;
|
||||
return PC_BOUNDS_INVALID;
|
||||
|
||||
/* When using the GNU linker, .gnu.linkonce. sections are used to
|
||||
eliminate duplicate copies of functions and vtables and such.
|
||||
@ -12108,7 +12124,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
|
||||
If this is a discarded function, mark the pc bounds as invalid,
|
||||
so that GDB will ignore it. */
|
||||
if (low == 0 && !dwarf2_per_objfile->has_section_at_zero)
|
||||
return PC_BOUNDS_NOT_PRESENT;
|
||||
return PC_BOUNDS_INVALID;
|
||||
|
||||
*lowpc = low;
|
||||
if (highpc)
|
||||
@ -12129,8 +12145,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
|
||||
CORE_ADDR low, high;
|
||||
struct die_info *child = die->child;
|
||||
|
||||
if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL)
|
||||
!= PC_BOUNDS_NOT_PRESENT)
|
||||
if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL) >= PC_BOUNDS_RANGES)
|
||||
{
|
||||
*lowpc = min (*lowpc, low);
|
||||
*highpc = max (*highpc, high);
|
||||
@ -12168,7 +12183,7 @@ get_scope_pc_bounds (struct die_info *die,
|
||||
CORE_ADDR current_low, current_high;
|
||||
|
||||
if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL)
|
||||
!= PC_BOUNDS_NOT_PRESENT)
|
||||
>= PC_BOUNDS_RANGES)
|
||||
{
|
||||
best_low = current_low;
|
||||
best_high = current_high;
|
||||
|
@ -1,3 +1,9 @@
|
||||
2016-05-30 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
PR c++/15231
|
||||
* gdb.ada/out_of_line_in_inlined.exp: Remove xfails.
|
||||
* gdb.dwarf2/dw2-lexical-block-bare.exp: New file.
|
||||
|
||||
2016-05-27 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* gdb.threads/attach-many-short-lived-threads.exp (bad_dejagnu):
|
||||
|
@ -23,20 +23,14 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug optimize=-O2}]
|
||||
|
||||
clean_restart ${testfile}
|
||||
|
||||
# GCC currently is missing a DW_AT_origin attribute in one of the
|
||||
# lexical blocks, preventing GDB from creating a symbol for the
|
||||
# subprogram we want to break on.
|
||||
setup_xfail "*-*-*"
|
||||
gdb_test "break foo_o224_021.child1.child2" \
|
||||
"Breakpoint \[0-9\]+ at.*: file .*foo_o224_021.adb, line \[0-9\]+."
|
||||
|
||||
gdb_run_cmd
|
||||
setup_xfail "*-*-*"
|
||||
gdb_test "" \
|
||||
"Breakpoint $decimal, foo_o224_021\\.child1\\.child2 \\(s=\\.\\.\\.\\).*"
|
||||
|
||||
set opt_addr_in "($hex in)?"
|
||||
setup_xfail "*-*-*"
|
||||
gdb_test "bt" \
|
||||
[multi_line "#0 +$opt_addr_in +foo_o224_021\\.child1\\.child2 \\(s=\\.\\.\\.\\).*" \
|
||||
"#1 +$opt_addr_in +foo_o224_021\\.child1 \\(\\).*" \
|
||||
|
70
gdb/testsuite/gdb.dwarf2/dw2-lexical-block-bare.exp
Normal file
70
gdb/testsuite/gdb.dwarf2/dw2-lexical-block-bare.exp
Normal file
@ -0,0 +1,70 @@
|
||||
# Copyright 2016 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
|
||||
|
||||
# This test can only be run on targets which support DWARF-2 and use gas.
|
||||
if {![dwarf2_support]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
standard_testfile .S main.c
|
||||
|
||||
# Make some DWARF for the test.
|
||||
set asm_file [standard_output_file $srcfile]
|
||||
Dwarf::assemble $asm_file {
|
||||
cu {} {
|
||||
compile_unit {
|
||||
{low_pc [gdb_target_symbol main] DW_FORM_addr}
|
||||
{high_pc [gdb_target_symbol main]+0x10000 DW_FORM_addr}
|
||||
} {
|
||||
declare_labels integer_label
|
||||
|
||||
integer_label: DW_TAG_base_type {
|
||||
{DW_AT_byte_size 4 DW_FORM_sdata}
|
||||
{DW_AT_encoding @DW_ATE_signed}
|
||||
{DW_AT_name integer}
|
||||
}
|
||||
|
||||
DW_TAG_subprogram {
|
||||
{name main}
|
||||
{DW_AT_external 1 flag}
|
||||
{low_pc [gdb_target_symbol main] DW_FORM_addr}
|
||||
{high_pc [gdb_target_symbol main]+0x10000 DW_FORM_addr}
|
||||
} {
|
||||
DW_TAG_lexical_block {
|
||||
} {
|
||||
DW_TAG_variable {
|
||||
{DW_AT_name testvar}
|
||||
{DW_AT_type :$integer_label}
|
||||
{DW_AT_external 1 flag}
|
||||
{DW_AT_location {
|
||||
DW_OP_addr [gdb_target_symbol main]
|
||||
} SPECIAL_expr}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} \
|
||||
[list $srcfile2 $asm_file] {nodebug}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
runto_main
|
||||
|
||||
# FAILing GDB did print: No symbol "testvar" in current context.
|
||||
gdb_test "p testvar" { = -?[0-9]+}
|
Loading…
x
Reference in New Issue
Block a user