This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] Fix PR 9675 - _static_ variables in C++ constructors
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Sun, 21 Dec 2008 19:54:28 +0100
- Subject: [patch] Fix PR 9675 - _static_ variables in C++ constructors
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 <jan.kratochvil@redhat.com>
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 <jan.kratochvil@redhat.com>
* 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 <http://www.gnu.org/licenses/>.
+ */
+
+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 <http://www.gnu.org/licenses/>.
+
+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.*"