[RFA:] testsuite: robustify g++.old-deja/g++.eh/badalloc1.C for 64-bit systems

Hans-Peter Nilsson hans-peter.nilsson@axis.com
Tue Sep 2 10:28:00 GMT 2014

In a native x86_64-linux toolchain in which
eh-table-registration is done explicitly (i.e. dl_iterate_phdr
and PT_GNU_EH_FRAME is *not* assumed, as that eliminates the
issue), the memory overhead for exception-initialization goes
beyond the 32768 bytes assumed in badalloc1.C and the test fails
for reasons not intended by the test.  You may think that's
uninteresting, but presumably there are other 64-bit-systems,
perhaps even GNU-based, that act similarly.

For EH tables registered with the __register_frame_info scheme
(let's call it eh-registry as opposed to eh-phdr), the incoming
tables are not assumed to be sorted.  EH initialization then
does an initial sorting at the first exception, in which there
are calls to malloc for arrays for the sorted tables.  This is
noticable in badalloc1.C as it overrides malloc.  All this
happens at that first "try{fn_throw();}" with the related
comment, i.e. before the "fail = 1" and the actual test in
badalloc1.C.  (There are other calls to malloc for other
unrelated initialization tasks, but for glibc systems these
resolve to a malloc in the dynamic linker.)  The sequence of
calls to malloc in badalloc1.C go like this:

Size   Purpose                      Function name
132    Core exception data.         __cxxabiv1::__cxa_allocate_exception
88     EH table for "badalloc1"     start_fde_sort
       program, 9 FDE:s for the     " (ditto)
       "linear" table.              "
88     Ditto the "erratic" table.   "
19176  Similar 2395 FDE:s for the   "
       libstdc++ library, "linear". "
19176  Ditto the "erratic" table.   "

The "boom" is simply the arena size check failing in the
badalloc1.C malloc:
  // Verify that we didn't run out of memory before getting initialized.
  if (pos > arena_size)
    abort ();

It seems the arena_size=32768 bytes estimate was from the
32-bit-systems era (svn logs indicate 2000).  Just scaling it
accordingly works fine, and we get to see the rest of the
1344   166 FDE:s in libgcc_s, "linear" table
1344   Ditto "erratic".

For a -m32 run, the corresponding allocation-size series is
100, 66, 66, 9592, 9592, 648, 648.

(*) for one reason or another.  Maybe the GNU linker is not used
or *really* outdated (before 2001-12-13, 2.12) or glibc is
*really* outdated (before 2001-07-25, 2.2.4).  Or inhibit_libc
accidentally set, or a compatibility scheme forcing eh-registry.
More about that in a later post.

Having investigated the related test-suite failure, I suggest to
eliminate it by robustifying the arena size a bit (or 32 :).  I
don't touch the other arena_size definitions because (1) those
numbers are presumably already fine for the related systems,
those still alive, and (2) I don't like changing stuff I cannot

Other observations: I guess there are similar copyright notices
in the test-suite may need some general attention.  The xfail
list may benefit from tweaking; at least replacing the xstormy16
with int32plus or similar to cover the array size overflowing
16-bit addresses.

Ok to commit?  (Note the changelog-conditional-prefix
continued-line format.)


	* g++.old-deja/g++.eh/badalloc1.C [!STACK_SIZE && !__FreeBSD__]
	[!__sun__ && !__hpux__] (arena_size): Scale according to
	target pointer size.

Index: g++.old-deja/g++.eh/badalloc1.C
--- g++.old-deja/g++.eh/badalloc1.C	(revision 214810)
+++ g++.old-deja/g++.eh/badalloc1.C	(working copy)
@@ -3,7 +3,7 @@
 // itself call malloc(), and will fail if there is no more
 // memory available.
 // { dg-do run { xfail { { xstormy16-*-* *-*-darwin[3-7]* } || vxworks_rtp } } }
-// Copyright (C) 2000, 2002, 2003, 2010, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2000, 2002, 2003, 2010, 2012, 2014 Free Software Foundation, Inc.
 // Contributed by Nathan Sidwell 6 June 2000 <nathan@codesourcery.com>
 // Check we can throw a bad_alloc exception when malloc dies.
@@ -23,7 +23,10 @@ const int arena_size = 256;
 // FreeBSD 5 now requires over 131072 bytes.
 const int arena_size = 262144;
-const int arena_size = 32768;
+// Because pointers make up the bulk of our exception-initialization
+// allocations, we scale by the pointer size from the original
+// 32-bit-systems-based estimate.
+const int arena_size = 32768 * ((sizeof (void *) + 3)/4);
brgds, H-P

More information about the Gcc-patches mailing list