c/4259: dwarf2out.c ignores the garbage collector
Tim Freeman
tim@fungible.com
Sun Sep 9 13:11:00 GMT 2001
From: rodrigc@gcc.gnu.org
> (1) reformat your patch according to the guidelines at:
> http://gcc.gnu.org/contribute.html
Okay.
>A description of the bug and how your patch fixes this bug.
dwarf2out.c has two static arrays of trees that it didn't register as
roots for the garbage collector. Thus, if you build a big-enough C++
routine that causes dwarf2out to make serious use of these arrays, the
values in these arrays may be collected prematurely. This can lead to
a core dump if the memory happens to be reused soon enough, or it will
lead to an immediate error if you configured with --enable-checking.
The fix is to transform the arrays into varray's and to declare them
as garbage collector roots.
This is bugs 4529, 4215, and 4212.
>It is strongly recommended the patch should add testcases for
>any new features added and any bugs fixed to the testsuite, if not
>already there.
A test case was included with bug 4215, but it only works when you
compile gcc with --enable-checking. Otherwise, the bug is hard to
reproduce; the original segmentation fault (bug 4212) would go away if
the name of the input file was changed. I don't know if the name of
the directory was significant. Also, the test case is uncomfortably
large. I don't know how to construct a good test case for this.
>A ChangeLog entry as plaintext
2001-09-09 Tim Freeman <tim@fungibole.com>
* dwarf2out.c (incomplete_types, decl_scope_table): Make them
into varray's and register them as roots with the garbage
collector so they are not collected too soon.
>A list of targets where the patch survived a bootstrap of GCC.
i386. I turned on --enable-checking for this bootstrap because the
most reliable symptom was a failed tree check. I turned on
--enable-debug for this bootstrap because the bug happens when writing
debug records to an object file.
>The patch itself.
*** dwarf2out.c 2001/08/22 14:35:01 1.306
--- dwarf2out.c 2001/09/09 19:37:38
*************** static unsigned decl_die_table_in_use;
*** 3273,3290 ****
of declaration scopes at the current scope and containing
scopes. This table is used to find the proper place to
define type declaration DIE's. */
! static tree *decl_scope_table;
- /* Number of elements currently allocated for the decl_scope_table. */
- static int decl_scope_table_allocated;
-
- /* Current level of nesting of declaration scopes. */
- static int decl_scope_depth;
-
- /* Size (in elements) of increments by which we may expand the
- decl_scope_table. */
- #define DECL_SCOPE_TABLE_INCREMENT 64
-
/* A pointer to the base of a list of references to DIE's that
are uniquely identified by their tag, presence/absence of
children DIE's, and list of attribute/value pairs. */
--- 3273,3280 ----
of declaration scopes at the current scope and containing
scopes. This table is used to find the proper place to
define type declaration DIE's. */
! varray_type decl_scope_table;
/* A pointer to the base of a list of references to DIE's that
are uniquely identified by their tag, presence/absence of
children DIE's, and list of attribute/value pairs. */
*************** static unsigned ranges_table_in_use;
*** 3368,3388 ****
static unsigned have_location_lists;
/* A pointer to the base of a list of incomplete types which might be
! completed at some later time. */
!
! static tree *incomplete_types_list;
- /* Number of elements currently allocated for the incomplete_types_list. */
- static unsigned incomplete_types_allocated;
-
- /* Number of elements of incomplete_types_list currently in use. */
- static unsigned incomplete_types;
-
- /* Size (in elements) of increments by which we may expand the incomplete
- types list. Actually, a single hunk of space of this size should
- be enough for most typical programs. */
- #define INCOMPLETE_TYPES_INCREMENT 64
-
/* Record whether the function being analyzed contains inlined functions. */
static int current_function_has_inlines;
#if 0 && defined (MIPS_DEBUGGING_INFO)
--- 3358,3369 ----
static unsigned have_location_lists;
/* A pointer to the base of a list of incomplete types which might be
! completed at some later time. incomplete_types_list needs to be a VARRAY
! because we want to tell the garbage collector about it. If we don't tell
! the garbage collector about it, we can garbage collect live data.
! Bug 4215.*/
! varray_type incomplete_types;
/* Record whether the function being analyzed contains inlined functions. */
static int current_function_has_inlines;
#if 0 && defined (MIPS_DEBUGGING_INFO)
*************** static void
*** 9166,9191 ****
push_decl_scope (scope)
tree scope;
{
! /* Make room in the decl_scope_table, if necessary. */
! if (decl_scope_table_allocated == decl_scope_depth)
! {
! decl_scope_table_allocated += DECL_SCOPE_TABLE_INCREMENT;
! decl_scope_table
! = (tree *) xrealloc (decl_scope_table,
! decl_scope_table_allocated * sizeof (tree));
! }
!
! decl_scope_table[decl_scope_depth] = scope;
! decl_scope_depth++;
}
/* Pop a declaration scope. */
static inline void
pop_decl_scope ()
{
! if (decl_scope_depth <= 0)
abort ();
! --decl_scope_depth;
}
/* Return the DIE for the scope that immediately contains this type.
--- 9147,9162 ----
push_decl_scope (scope)
tree scope;
{
! VARRAY_PUSH_TREE (decl_scope_table, scope);
}
/* Pop a declaration scope. */
static inline void
pop_decl_scope ()
{
! if (VARRAY_ACTIVE_SIZE (decl_scope_table) <= 0)
abort ();
! VARRAY_POP (decl_scope_table);
}
/* Return the DIE for the scope that immediately contains this type.
*************** scope_die_for (t, context_die)
*** 9227,9234 ****
first we check to see if we're in the middle of emitting it
so we know where the new DIE should go. */
! for (i = decl_scope_depth - 1; i >= 0; --i)
! if (decl_scope_table[i] == containing_scope)
break;
if (i < 0)
--- 9198,9205 ----
first we check to see if we're in the middle of emitting it
so we know where the new DIE should go. */
! for (i = VARRAY_ACTIVE_SIZE (decl_scope_table) - 1; i >= 0; --i)
! if (VARRAY_TREE (decl_scope_table, i) == containing_scope)
break;
if (i < 0)
*************** gen_entry_point_die (decl, context_die)
*** 9482,9501 ****
#endif
/* Remember a type in the incomplete_types_list. */
-
static void
add_incomplete_type (type)
tree type;
{
! if (incomplete_types == incomplete_types_allocated)
! {
! incomplete_types_allocated += INCOMPLETE_TYPES_INCREMENT;
! incomplete_types_list
! = (tree *) xrealloc (incomplete_types_list,
! sizeof (tree) * incomplete_types_allocated);
! }
!
! incomplete_types_list[incomplete_types++] = type;
}
/* Walk through the list of incomplete types again, trying once more to
--- 9453,9463 ----
#endif
/* Remember a type in the incomplete_types_list. */
static void
add_incomplete_type (type)
tree type;
{
! VARRAY_PUSH_TREE (incomplete_types, type);
}
/* Walk through the list of incomplete types again, trying once more to
*************** add_incomplete_type (type)
*** 9504,9516 ****
static void
retry_incomplete_types ()
{
! register tree type;
!
! while (incomplete_types)
{
! --incomplete_types;
! type = incomplete_types_list[incomplete_types];
! gen_type_die (type, comp_unit_die);
}
}
--- 9466,9475 ----
static void
retry_incomplete_types ()
{
! int i;
! for (i = VARRAY_ACTIVE_SIZE (incomplete_types) - 1; i >= 0; i--)
{
! gen_type_die (VARRAY_TREE (incomplete_types, i), comp_unit_die);
}
}
*************** dwarf2out_init (main_input_filename)
*** 11645,11654 ****
decl_die_table_in_use = 0;
/* Allocate the initial hunk of the decl_scope_table. */
! decl_scope_table
! = (tree *) xcalloc (DECL_SCOPE_TABLE_INCREMENT, sizeof (tree));
! decl_scope_table_allocated = DECL_SCOPE_TABLE_INCREMENT;
! decl_scope_depth = 0;
/* Allocate the initial hunk of the abbrev_die_table. */
abbrev_die_table
--- 11604,11611 ----
decl_die_table_in_use = 0;
/* Allocate the initial hunk of the decl_scope_table. */
! VARRAY_TREE_INIT (decl_scope_table, 256, "decl_scope_table");
! ggc_add_tree_varray_root (&decl_scope_table, 1);
/* Allocate the initial hunk of the abbrev_die_table. */
abbrev_die_table
*************** dwarf2out_init (main_input_filename)
*** 11672,11677 ****
--- 11629,11637 ----
taken as being relative to the directory from which the compiler was
invoked when the given (base) source file was compiled. */
comp_unit_die = gen_compile_unit_die (main_input_filename);
+
+ VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
+ ggc_add_tree_varray_root (&incomplete_types, 1);
VARRAY_RTX_INIT (used_rtx_varray, 32, "used_rtx_varray");
ggc_add_rtx_varray_root (&used_rtx_varray, 1);
More information about the Gcc-bugs
mailing list