Home | History | Annotate | Download | only in jni
      1 // This fails for VxWorks RTPs because the initialization of
      2 // __cxa_allocate_exception's emergency buffer mutex will
      3 // itself call malloc(), and will fail if there is no more
      4 // memory available.
      5 // { dg-do run { xfail { { xstormy16-*-* *-*-darwin[3-7]* } || vxworks_rtp } } }
      6 // Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
      7 // Contributed by Nathan Sidwell 6 June 2000 <nathan (at) codesourcery.com>
      8 
      9 // Check we can throw a bad_alloc exception when malloc dies.
     10 
     11 typedef __SIZE_TYPE__ size_t;
     12 extern "C" void abort();
     13 extern "C" void *memcpy(void *, const void *, size_t);
     14 
     15 // Assume that STACK_SIZE defined implies a system that does not have a
     16 // large data space either, and additionally that we're not linking against
     17 // a shared libstdc++ (which requires quite a bit more initialization space).
     18 #ifdef STACK_SIZE
     19 const int arena_size = 256;
     20 #else
     21 #if defined(__FreeBSD__) || defined(__sun__) || defined(__hpux__)
     22 // FreeBSD, Solaris and HP-UX with threads require even more
     23 // space at initialization time.  FreeBSD 5 now requires over 131072 bytes.
     24 const int arena_size = 262144;
     25 #else
     26 const int arena_size = 32768;
     27 #endif
     28 #endif
     29 
     30 struct object
     31 {
     32   size_t size __attribute__((aligned));
     33 };
     34 
     35 static char arena[arena_size] __attribute__((aligned));
     36 static size_t pos;
     37 
     38 // So we can force a failure when needed.
     39 static int fail;
     40 
     41 extern "C" void *malloc (size_t size)
     42 {
     43   object *p = reinterpret_cast<object *>(&arena[pos]);
     44 
     45   if (fail)
     46     return 0;
     47 
     48   p->size = size;
     49   size = (size + __alignof__(object) - 1) & - __alignof__(object);
     50   pos += size + sizeof(object);
     51 
     52   // Verify that we didn't run out of memory before getting initialized.
     53   if (pos > arena_size)
     54     abort ();
     55 
     56   return p + 1;
     57 }
     58 
     59 extern "C" void free (void *)
     60 {
     61 }
     62 
     63 extern "C" void *realloc (void *p, size_t size)
     64 {
     65   void *r;
     66 
     67   if (p)
     68     {
     69       object *o = reinterpret_cast<object *>(p) - 1;
     70       size_t old_size = o->size;
     71 
     72       if (old_size >= size)
     73 	{
     74 	  r = p;
     75 	  o->size = size;
     76 	}
     77       else
     78 	{
     79 	  r = malloc (size);
     80 	  memcpy (r, p, old_size);
     81 	  free (p);
     82 	}
     83     }
     84   else
     85     r = malloc (size);
     86 
     87   return r;
     88 }
     89 
     90 void fn_throw() throw(int)
     91 {
     92   throw 1;
     93 }
     94 
     95 void fn_rethrow() throw(int)
     96 {
     97   try{fn_throw();}
     98   catch(int a){
     99     throw;}
    100 }
    101 
    102 void fn_catchthrow() throw(int)
    103 {
    104   try{fn_throw();}
    105   catch(int a){
    106     throw a + 1;}
    107 }
    108 
    109 int main()
    110 {
    111   /* On some systems (including FreeBSD and Solaris 2.10),
    112      __cxa_get_globals will try to call "malloc" when threads are in
    113      use.  Therefore, we throw one exception up front so that
    114      __cxa_get_globals is all set up.  Ideally, this would not be
    115      necessary, but it is a well-known idiom, and using this technique
    116      means that we can still validate the fact that exceptions can be
    117      thrown when malloc fails.  */
    118   try{fn_throw();}
    119   catch(int a){}
    120 
    121   fail = 1;
    122 
    123   try{fn_throw();}
    124   catch(int a){}
    125 
    126   try{fn_rethrow();}
    127   catch(int a){}
    128 
    129   try{fn_catchthrow();}
    130   catch(int a){}
    131 
    132   return 0;
    133 }
    134