From patchwork Sun May 29 14:10:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 12599 Received: (qmail 98963 invoked by alias); 29 May 2016 14:11:01 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 98941 invoked by uid 89); 29 May 2016 14:11:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=*-*-* X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sun, 29 May 2016 14:10:50 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E42E3C05B1DB for ; Sun, 29 May 2016 14:10:48 +0000 (UTC) Received: from host1.jankratochvil.net (ovpn-116-44.ams2.redhat.com [10.36.116.44]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u4TEAhHC012314 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 29 May 2016 10:10:45 -0400 Date: Sun, 29 May 2016 16:10:43 +0200 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patchv2 2/2] PR 15231: import bare DW_TAG_lexical_block Message-ID: <20160529141043.GB13685@host1.jankratochvil.net> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.6.1 (2016-04-27) X-IsSubscribed: yes Hi, 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): [...] 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 out of line functions nested inside inline functions. So I have removed that xfail. No regression on Fedora Rawhide. Thanks, Jan 2016-05-29 Jan Kratochvil 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-14 Jan Kratochvil PR c++/15231 * gdb.ada/out_of_line_in_inlined.exp: Remove xfails. * gdb.dwarf2/dw2-lexical-block-bare.exp: New file. --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1610,10 +1610,13 @@ static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *, values. */ 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, @@ -6018,7 +6021,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, - has_pc_info == pc_bounds_not_present, cu); + has_pc_info <= pc_bounds_invalid, cu); /* If we didn't find a lowpc, set it to highpc to avoid complaints from `maint check'. */ @@ -6027,7 +6030,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 (has_pc_info == pc_bounds_not_present) + if (has_pc_info <= pc_bounds_invalid) { best_lowpc = lowpc; best_highpc = highpc; @@ -11389,7 +11392,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)) @@ -11551,9 +11554,19 @@ 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 && 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); @@ -11763,7 +11776,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]"), @@ -12040,7 +12053,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, @@ -12051,7 +12064,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) @@ -12066,7 +12079,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; @@ -12088,15 +12101,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. @@ -12107,7 +12122,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) @@ -12128,8 +12143,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); @@ -12167,7 +12181,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; --- a/gdb/testsuite/gdb.ada/out_of_line_in_inlined.exp +++ b/gdb/testsuite/gdb.ada/out_of_line_in_inlined.exp @@ -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 \\(\\).*" \ --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-lexical-block-bare.exp @@ -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 . +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]+}