File indexing completed on 2025-05-11 08:24:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <rtems.h>
0026 #include <rtems/bspIo.h>
0027 #include <rtems/test-info.h>
0028 #include <rtems/sysinit.h>
0029
0030 #include <cstdio>
0031 #include <cstdlib>
0032 #include <cstring>
0033 #include <stdexcept>
0034
0035 #ifdef RTEMS_TEST_IO_STREAM
0036 #include <iostream>
0037 #endif
0038
0039 const char rtems_test_name[] = "CONSTRUCTOR/DESTRUCTOR";
0040
0041 extern "C"
0042 {
0043 #include <tmacros.h>
0044 extern rtems_task main_task(rtems_task_argument);
0045 }
0046
0047 static int num_inst = 0;
0048
0049 static void check_end_of_test(void)
0050 {
0051 if ( num_inst == 0 ) {
0052 TEST_END();
0053 }
0054 }
0055
0056 class AClass {
0057 public:
0058 AClass(const char *p = "LOCAL" ) : ptr( p )
0059 {
0060 num_inst++;
0061 printf(
0062 "%s: Hey I'm in base class constructor number %d for %p.\n",
0063 p, num_inst, this
0064 );
0065
0066
0067
0068
0069
0070 string = new char[50];
0071 sprintf(string, "Instantiation order %d", num_inst);
0072 };
0073
0074 virtual ~AClass()
0075 {
0076
0077 printk(
0078 "%s: Hey I'm in base class destructor number %d for %p.\n",
0079 ptr, num_inst, this
0080 );
0081 printk("Derived class - %s\n", string);
0082 num_inst--;
0083 check_end_of_test();
0084 };
0085
0086 #if __cplusplus >= 201103L
0087 AClass& operator=(const AClass&) = default;
0088 #endif
0089
0090 virtual void print() { printf("%s\n", string); };
0091
0092 protected:
0093 char *string;
0094 const char *ptr;
0095 };
0096
0097 class BClass : public AClass {
0098 public:
0099 BClass(const char *p = "LOCAL" ) : AClass( p )
0100 {
0101 num_inst++;
0102 printf(
0103 "%s: Hey I'm in derived class constructor number %d for %p.\n",
0104 p, num_inst, this
0105 );
0106
0107
0108
0109
0110
0111 string = new char[50];
0112 sprintf(string, "Instantiation order %d", num_inst);
0113 };
0114
0115 ~BClass()
0116 {
0117 printk(
0118 "%s: Hey I'm in derived class destructor number %d for %p.\n",
0119 ptr, num_inst,
0120 this
0121 );
0122 printk("Derived class - %s\n", string);
0123 num_inst--;
0124 check_end_of_test();
0125 };
0126
0127 void print() { printf("Derived class - %s\n", string); }
0128 };
0129
0130
0131 class RtemsException
0132 {
0133 public:
0134
0135 RtemsException( const char *module, int ln, int err = 0 )
0136 : error( err ), line( ln ), file( module )
0137 {
0138 printf( "RtemsException raised=File:%s, Line:%d, Error=%X\n",
0139 file, line, error );
0140 }
0141
0142 void show()
0143 {
0144 printf( "RtemsException ---> File:%s, Line:%d, Error=%X\n",
0145 file, line, error );
0146 }
0147
0148 private:
0149 int error;
0150 int line;
0151 const char *file;
0152
0153 };
0154
0155
0156
0157 AClass foo( "GLOBAL" );
0158 BClass foobar( "GLOBAL" );
0159
0160 void
0161 cdtest(void)
0162 {
0163 AClass bar, blech, blah;
0164 BClass bleak;
0165
0166 #ifdef RTEMS_TEST_IO_STREAM
0167 std::cout << "Testing a C++ I/O stream" << std::endl;
0168 #else
0169 printf("IO Stream not tested\n");
0170 #endif
0171 bar = blech;
0172 rtems_task_wake_after( 5 * rtems_clock_get_ticks_per_second() );
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182 static void foo_function()
0183 {
0184 try
0185 {
0186 throw "foo_function() throw this exception";
0187 }
0188 catch( const char *e )
0189 {
0190 printf( "foo_function() catch block called:\n < %s >\n", e );
0191 throw "foo_function() re-throwing execption...";
0192 }
0193 }
0194
0195 rtems_task main_task(
0196 rtems_task_argument
0197 )
0198 {
0199 cdtest();
0200
0201 printf( "*** TESTING C++ EXCEPTIONS ***\n\n" );
0202
0203 try
0204 {
0205 foo_function();
0206 }
0207 catch( const char *e )
0208 {
0209 printf( "Success catching a char * exception\n%s\n", e );
0210 }
0211
0212 try
0213 {
0214 throw std::runtime_error("thrown std::runtime object");
0215 }
0216 catch (std::exception const& e)
0217 {
0218 printf("throw std::runtime: caught: %s\n", e.what());
0219 }
0220
0221 try
0222 {
0223 printf( "throw an instance based exception\n" );
0224 throw RtemsException( __FILE__, __LINE__, 0x55 );
0225 }
0226 catch( RtemsException & ex )
0227 {
0228 printf( "Success catching RtemsException...\n" );
0229 ex.show();
0230 }
0231 catch(...)
0232 {
0233 printf( "Caught another exception.\n" );
0234 }
0235 printf( "Exceptions are working properly.\n" );
0236 rtems_task_wake_after( 5 * rtems_clock_get_ticks_per_second() );
0237 printf( "Global Dtors should be called after this line....\n" );
0238 exit(0);
0239 }
0240
0241
0242
0243
0244
0245
0246
0247 #if defined(__arm__)
0248 #define CAN_DO_EXCEPTIONS_DURING_SYSINIT
0249 #endif
0250
0251 #ifdef CAN_DO_EXCEPTIONS_DURING_SYSINIT
0252 static void early_exception()
0253 {
0254 try
0255 {
0256 throw "early exception";
0257 }
0258 catch( const char *e )
0259 {
0260 rtems_test_assert(strcmp(e, "early exception") == 0);
0261 throw "early exception 2";
0262 }
0263 }
0264 #endif
0265
0266 static void test_exceptions_during_system_init()
0267 {
0268 TEST_BEGIN();
0269
0270 #ifdef CAN_DO_EXCEPTIONS_DURING_SYSINIT
0271 try
0272 {
0273 early_exception();
0274 }
0275 catch( const char *e )
0276 {
0277 rtems_test_assert(strcmp(e, "early exception 2") == 0);
0278 }
0279 #endif
0280 }
0281
0282 RTEMS_SYSINIT_ITEM(
0283 test_exceptions_during_system_init,
0284 RTEMS_SYSINIT_IDLE_THREADS,
0285 RTEMS_SYSINIT_ORDER_LAST
0286 );