1 //===--------------------------- test_vector2.cpp -------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "cxxabi.h" 11 12 #include <iostream> 13 #include <cstdlib> 14 15 void my_terminate () { exit ( 0 ); } 16 17 // Wrapper routines 18 void *my_alloc2 ( size_t sz ) { 19 void *p = std::malloc ( sz ); 20 // std::printf ( "Allocated %ld bytes at %lx\n", sz, (unsigned long) p ); 21 return p; 22 } 23 24 void my_dealloc2 ( void *p ) { 25 // std::printf ( "Freeing %lx\n", (unsigned long) p ); 26 std::free ( p ); 27 } 28 29 void my_dealloc3 ( void *p, size_t sz ) { 30 // std::printf ( "Freeing %lx (size %ld)\n", (unsigned long) p, sz ); 31 std::free ( p ); 32 } 33 34 void my_construct ( void *p ) { 35 // std::printf ( "Constructing %lx\n", (unsigned long) p ); 36 } 37 38 void my_destruct ( void *p ) { 39 // std::printf ( "Destructing %lx\n", (unsigned long) p ); 40 } 41 42 int gCounter; 43 void count_construct ( void *p ) { ++gCounter; } 44 void count_destruct ( void *p ) { --gCounter; } 45 46 47 int gConstructorCounter; 48 int gConstructorThrowTarget; 49 int gDestructorCounter; 50 int gDestructorThrowTarget; 51 void throw_construct ( void *p ) { if ( gConstructorCounter == gConstructorThrowTarget ) throw 1; ++gConstructorCounter; } 52 void throw_destruct ( void *p ) { if ( ++gDestructorCounter == gDestructorThrowTarget ) throw 2; } 53 54 struct vec_on_stack { 55 void *storage; 56 vec_on_stack () : storage ( __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct )) {} 57 ~vec_on_stack () { __cxxabiv1::__cxa_vec_delete ( storage, 40, 8, throw_destruct ); } 58 }; 59 60 61 // Make sure the constructors and destructors are matched 62 void test_exception_in_destructor ( ) { 63 64 // Try throwing from a destructor while unwinding the stack -- should abort 65 gConstructorCounter = gDestructorCounter = 0; 66 gConstructorThrowTarget = -1; 67 gDestructorThrowTarget = 5; 68 try { 69 vec_on_stack v; 70 throw 3; 71 } 72 catch ( int i ) {} 73 74 std::cerr << "should never get here" << std::endl; 75 } 76 77 78 79 int main ( int argc, char *argv [] ) { 80 std::set_terminate ( my_terminate ); 81 test_exception_in_destructor (); 82 return 1; // we failed if we get here 83 } 84