new throwing bad_alloc patch

Kriang Lerdsuwanakij lerdsuwa@scf-fs.usc.edu
Fri Oct 10 22:58:00 GMT 1997


Hi,

I found a better way than the one in my previous post about the behavior
of new.  I also provide a patch below against files in gcc/ and gcc/cp/.

The idea is like this:

- new by default throw bad_alloc when there is not enough memory.  It
also set a variable (__throw_by_new_handler).
- The variable is cleared if there is any catch block encountered during
stack unwinding (so that uncaught exception that occurs later is handled
properly by terminate).
- terminate displays virtual memory exhausted message if the variable is
set and dumps core otherwise.

There is no new gcc option needed.  It also provides backward
compatibily for old C++ programs.  The only issue here is that it is not
thread-safe due to the way the variable is used.

--
Kriang
lerdsuwa@scf.usc.edu


[ Changes inside gcc/cp subdirectory ]

Fri Oct 10 20:02:58 1997  Kriang Lerdsuwanakij  <lerdsuwa@scf.usc.edu>

	* exception.cc (__throw_bad_alloc): New function.
	* tinfo2.cc (__throw_type_match_rtti): Disable memory exhausted
	message when called.


diff -u exception.cc.save exception.cc
--- exception.cc.save	Fri Oct 10 19:11:48 1997
+++ exception.cc	Fri Oct 10 20:02:58 1997
@@ -29,6 +29,7 @@
 
 #include "typeinfo"
 #include "exception"
+#include "new"
 
 /* Define terminate, unexpected, set_terminate, set_unexpected as
    well as the default terminate func and default unexpected func.  */
@@ -89,6 +90,12 @@
 __throw_bad_exception (void)
 {
   throw bad_exception ();
+}
+
+extern "C" void
+__throw_bad_alloc (void)
+{
+  throw bad_alloc ();
 }
 
 bool
diff -u tinfo2.cc.save tinfo2.cc
--- tinfo2.cc.save	Fri Oct 10 20:00:29 1997
+++ tinfo2.cc	Fri Oct 10 20:00:29 1997
@@ -118,13 +118,14 @@
 /* Low level match routine used by compiler to match types of catch
    variables and thrown objects.  */
 
+extern "C" int __throw_by_new_handler;
+
 extern "C" void*
 __throw_type_match_rtti (void *catch_type_r, void *throw_type_r, void
*objptr)
 {
   const type_info &catch_type = *(const type_info *)catch_type_r;
   const type_info &throw_type = *(const type_info *)throw_type_r;
   
+  __throw_by_new_handler = 0;
+
   if (catch_type == throw_type)




===============================================================================
[ Changes inside gcc subdirectory ]

Fri Oct 10 21:17:58 1997  Kriang Lerdsuwanakij  <lerdsuwa@scf.usc.edu>

	* libgcc2.c (__default_new_handler): Throw bad_alloc rather than
	display error message.
	(__old_default_new_handler): New function.
	(__default_terminate): Call __old_default_new_handler when there is
	no exception handler.
	(__throw_type_match): Disable memory exhausted message when called.

--- libgcc2.c.save	Fri Oct 10 19:11:06 1997
+++ libgcc2.c	Fri Oct 10 21:17:58 1997
@@ -2513,8 +2513,10 @@
 
 typedef void (*vfp)(void);
 void __default_new_handler (void);
+void __throw_bad_alloc (void);
 
 vfp __new_handler = (vfp) 0;
+int __throw_by_new_handler = 0;
 
 vfp
 set_new_handler (vfp handler)
@@ -2530,7 +2532,7 @@
 #define MESSAGE "Virtual memory exceeded in `new'\n"
 
 void
-__default_new_handler ()
+__old_default_new_handler ()
 {
 #ifndef inhibit_libc
   /* don't use fprintf (stderr, ...) because it may need to call
malloc.  */
@@ -2542,6 +2544,18 @@
      may cause a loop.  */
   _exit (-1);
 }
+
+void
+__default_new_handler ()
+{
+  /* true if there is not enough memory when we are constructing the 
+     bad_alloc object */
+  if (__throw_by_new_handler)
+    __old_default_new_handler ();
+
+  __throw_by_new_handler = 1;
+  __throw_bad_alloc ();
+}
 #endif
 
 #ifdef L_op_delete
@@ -3109,11 +3123,16 @@
 
 /* Shared exception handling support routines.  */
 
+void __old_default_new_handler (void);
+
 extern void *__eh_type;
+extern int __throw_by_new_handler;
 
 void
 __default_terminate ()
 {
+  if (__throw_by_new_handler)
+    __old_default_new_handler ();
   abort ();
 }
 
@@ -3128,6 +3147,7 @@
 void *
 __throw_type_match (void *catch_type, void *throw_type, void *obj)
 {
+  __throw_by_new_handler = 0;
 #if 0
  printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
 	 catch_type, throw_type);



More information about the Gcc mailing list