From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30061 invoked by alias); 21 Dec 2008 18:56:07 -0000 Received: (qmail 30052 invoked by uid 22791); 21 Dec 2008 18:56:06 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_13,KAM_MX,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx2.redhat.com (HELO mx2.redhat.com) (66.187.237.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 21 Dec 2008 18:54:34 +0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id mBLIsWVd011303 for ; Sun, 21 Dec 2008 13:54:32 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id mBLIsWfh015168 for ; Sun, 21 Dec 2008 13:54:32 -0500 Received: from host0.dyn.jankratochvil.net (sebastian-int.corp.redhat.com [172.16.52.221]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id mBLIsU19011452 for ; Sun, 21 Dec 2008 13:54:31 -0500 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.3/8.14.3) with ESMTP id mBLIsT4e030118 for ; Sun, 21 Dec 2008 19:54:29 +0100 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.3/8.14.2/Submit) id mBLIsTJG029531 for gdb-patches@sourceware.org; Sun, 21 Dec 2008 19:54:29 +0100 Date: Sun, 21 Dec 2008 18:56:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patch] Fix PR 9675 - _static_ variables in C++ constructors Message-ID: <20081221185428.GA27604@host0.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-12/txt/msg00367.txt.bz2 Hi, Fix visibility of _static_ variables in C++ constructors, as I saw it now even in GDB BZ: http://sourceware.org/bugzilla/show_bug.cgi?id=9675 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33044 https://bugzilla.redhat.com/show_bug.cgi?id=445912 (gdb) b 25 Breakpoint 1 at 0x400637: file /tmp/pr9675.C, line 25. (2 locations) (gdb) r Starting program: /tmp/pr9675 c_ = 1946 foofoo = 4196416 Breakpoint 1, A (this=0x7fffffffd3e0, a=34, b=56) at /tmp/pr9675.C:25 25 } -> before: (gdb) p c_ $1 = 1946 (gdb) p foofoo No symbol "foofoo" in current context. (gdb) after: (gdb) p c_ $1 = 1946 (gdb) p foofoo $2 = {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}, {4, 5, 6, 7}, {5, 6, 7, 8}} (gdb) q Regards, Jan 2008-12-21 Jan Kratochvil PR gdb/9675: * dwarf2read.c (unsigned_int_compar): New function. (read_func_scope): New variable die_children, initialize it. Process all DIEs of DW_AT_abstract_origin not being referenced by any of the children of the current DIE die. 2008-12-21 Jan Kratochvil * gdb.cp/abstract-origin.exp, gdb.cp/abstract-origin.cc: New test. --- gdb/dwarf2read.c 15 Nov 2008 18:49:50 -0000 1.291 +++ gdb/dwarf2read.c 21 Dec 2008 18:11:00 -0000 @@ -3032,6 +3032,15 @@ add_to_cu_func_list (const char *name, C cu->last_fn = thisfn; } +static int +unsigned_int_compar (const void *ap, const void *bp) +{ + unsigned int a = *(unsigned int *) ap; + unsigned int b = *(unsigned int *) bp; + + return (a > b) - (b > a); +} + static void read_func_scope (struct die_info *die, struct dwarf2_cu *cu) { @@ -3044,6 +3053,7 @@ read_func_scope (struct die_info *die, s char *name; CORE_ADDR baseaddr; struct block *block; + unsigned die_children_count; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -3080,14 +3090,89 @@ read_func_scope (struct die_info *die, s cu->list_in_scope = &local_symbols; - if (die->child != NULL) + child_die = die->child; + die_children_count = 0; + while (child_die && child_die->tag) { + process_die (child_die, cu); + child_die = sibling_die (child_die); + die_children_count++; + } + + /* DW_AT_abstract_origin inherits whole DIEs (not just their attributes). + Inherit only the children of the DW_AT_abstract_origin DIE not being + already referenced by DW_AT_abstract_origin from the children of the + current DIE. */ + attr = dwarf2_attr (die, DW_AT_abstract_origin, cu); + if (attr) + { + /* CU offsets which were referenced by children of the current DIE. */ + unsigned *offsets; + unsigned *offsets_end, *offsetp; + /* Parent of DIE - referenced by DW_AT_abstract_origin. */ + struct die_info *origin_die; + /* Iterator of the ORIGIN_DIE children. */ + struct die_info *origin_child_die; + struct cleanup *cleanups; + + origin_die = follow_die_ref (die, attr, &cu); + if (die->tag != origin_die->tag) + complaint (&symfile_complaints, + _("DIE 0x%x and its abstract origin 0x%x have different " + "tags"), + die->offset, origin_die->offset); + + offsets = xmalloc (sizeof (*offsets) * die_children_count); + cleanups = make_cleanup (xfree, offsets); + + offsets_end = offsets; child_die = die->child; while (child_die && child_die->tag) { - process_die (child_die, cu); + attr = dwarf2_attr (child_die, DW_AT_abstract_origin, cu); + if (!attr) + complaint (&symfile_complaints, + _("Child DIE 0x%x of DIE 0x%x has missing " + "DW_AT_abstract_origin"), child_die->offset, + die->offset); + else + { + struct die_info *child_origin_die; + + child_origin_die = follow_die_ref (child_die, attr, &cu); + if (child_die->tag != child_origin_die->tag) + complaint (&symfile_complaints, + _("Child DIE 0x%x and its abstract origin 0x%x have " + "different tags"), child_die->offset, + child_origin_die->offset); + *offsets_end++ = child_origin_die->offset; + } child_die = sibling_die (child_die); } + qsort (offsets, offsets_end - offsets, sizeof (*offsets), + unsigned_int_compar); + for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++) + if (offsetp[-1] == *offsetp) + complaint (&symfile_complaints, + _("Child DIEs of DIE 0x%x duplicitly abstract-origin " + "referenced DIE 0x%x"), die->offset, *offsetp); + + offsetp = offsets; + origin_child_die = origin_die->child; + while (origin_child_die && origin_child_die->tag) + { + /* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */ + while (offsetp < offsets_end && *offsetp < origin_child_die->offset) + offsetp++; + if (offsetp >= offsets_end || *offsetp > origin_child_die->offset) + { + /* Found that ORIGIN_CHILD_DIE is really not referenced. */ + process_die (origin_child_die, cu); + } + origin_child_die = sibling_die (origin_child_die); + } + + do_cleanups (cleanups); } new = pop_context (); --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.cp/abstract-origin.cc 21 Dec 2008 18:11:09 -0000 @@ -0,0 +1,42 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 . + */ + +extern void f (int *); + +class A +{ +public: + A(int i); +}; + +A::A(int i) +{ + static int *problem = new int(i); + f (problem); /* break-here */ +} + +void f (int *) +{ +} + +int +main (void) +{ + A a(42); + return 0; +} --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.cp/abstract-origin.exp 21 Dec 2008 18:11:09 -0000 @@ -0,0 +1,40 @@ +# Copyright 2008 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 . + +set testfile abstract-origin +set srcfile ${testfile}.cc +set binfile ${objdir}/${subdir}/${testfile} +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] { + untested abstract-origin + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break-here"] +gdb_continue_to_breakpoint "break-here" + +# The Bug was: No symbol "problem" in current context. +gdb_test "p problem" " = \\(int \\*\\) 0x.*"