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