00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #include <stdio.h>
00069 #include <stdlib.h>
00070 #include <string.h>
00071 #include <stdarg.h>
00072 #include <setjmp.h>
00073 #include <signal.h>
00074 #include <lal/LALStdio.h>
00075 #include <lal/LALStdlib.h>
00076
00077 NRCSID (LALMALLOCTESTC,"$Id: LALMallocTest.c,v 1.3 2007/06/08 14:41:54 bema Exp $");
00078
00079 char caughtMessage[1024];
00080 jmp_buf jump;
00081 FILE *mystderr;
00082
00083
00084 static int TestRaise( int sig, const char *fmt, ... )
00085 {
00086 va_list ap;
00087 va_start( ap, fmt );
00088 LALVsnprintf( caughtMessage, sizeof( caughtMessage ), fmt, ap );
00089 va_end( ap );
00090 longjmp( jump, sig );
00091 return -1;
00092 }
00093
00094 #define STR( a ) #a
00095 #define XSTR( a ) STR( a )
00096 #define LINE ":" XSTR( __LINE__ ) ")\n"
00097 #define trial( func, sig, msg ) \
00098 do { \
00099 int val; \
00100 if ( ! ( val = setjmp( jump ) ) ) \
00101 { \
00102 func; \
00103 if ( sig ) \
00104 { \
00105 fprintf( mystderr, "Error: no signal raised! (" #func LINE ); \
00106 return 1; \
00107 } \
00108 } \
00109 else \
00110 { \
00111 if ( val != sig ) \
00112 { \
00113 fprintf( mystderr, "Error: wrong signal raised! (" #func LINE ); \
00114 fprintf( mystderr, "Received: %d %s", val, caughtMessage ); \
00115 fprintf( mystderr, "Expected: %d %s\n", sig, msg ); \
00116 return 1; \
00117 } \
00118 if ( ! strstr( caughtMessage, msg ) ) \
00119 { \
00120 fprintf( mystderr, "Error: wrong message! (" #func LINE ); \
00121 fprintf( mystderr, "Received: %d %s", val, caughtMessage ); \
00122 fprintf( mystderr, "Expected: %d %s\n", sig, msg ); \
00123 return 1; \
00124 } \
00125 } \
00126 } \
00127 while ( 0 )
00128
00129 #define die( msg ) ( fputs( "Error: " #msg "\n", mystderr ), exit( 1 ), 1 )
00130
00131
00132 int lalDebugLevel = LALMEMDBG;
00133
00134
00135 size_t i;
00136 size_t j;
00137 size_t n;
00138 size_t *p;
00139 size_t *q;
00140 size_t *r;
00141 size_t *s;
00142 size_t **v;
00143
00144
00145 static int testOK( void )
00146 {
00147 int keep = lalDebugLevel;
00148
00149 lalDebugLevel &= ~( LALNMEMDBG | LALNMEMPAD | LALNMEMTRK );
00150 trial( p = LALMalloc( 1024 * sizeof( *p ) ), 0, "" );
00151 for ( i = 0; i < 1024; ++i ) p[i] = i;
00152 trial( q = LALCalloc( 1024, sizeof( *q ) ), 0, "" );
00153 for ( i = 0; i < 1024; ++i ) if ( q[i] ) die( memory not blanked );
00154 trial( p = LALRealloc( p, 4096 * sizeof( *p ) ), 0, "" );
00155 for ( i = 0; i < 1024; ++i ) if ( p[i] != i ) die( memory not copied );
00156 trial( q = LALRealloc( q, 0 ), 0, "" );
00157 if ( q ) die( memory not freed );
00158 trial( LALCheckMemoryLeaks(), SIGSEGV, "LALCheckMemoryLeaks: memory leak\n" );
00159 if ( *( p - 1 ) != (size_t)0xABadCafe ) die( wrong magic );
00160 if ( *( p - 2 ) != 4096 * sizeof( *p ) ) die( wrong size );
00161 trial( LALFree( p ), 0, "" );
00162 trial( LALCheckMemoryLeaks(), 0, "" );
00163
00164 lalDebugLevel |= LALNMEMPAD;
00165 trial( p = LALMalloc( 1024 * sizeof( *p ) ), 0, "" );
00166 for ( i = 0; i < 1024; ++i ) p[i] = i;
00167 trial( q = LALCalloc( 1024, sizeof( *q ) ), 0, "" );
00168 for ( i = 0; i < 1024; ++i ) if ( q[i] ) die( memory not blanked );
00169 trial( p = LALRealloc( p, 4096 * sizeof( *p ) ), 0, "" );
00170 for ( i = 0; i < 1024; ++i ) if ( p[i] != i ) die( memory not copied );
00171 trial( q = LALRealloc( q, 0 ), 0, "" );
00172 if ( q ) die( memory not freed );
00173 trial( LALCheckMemoryLeaks(), SIGSEGV, "LALCheckMemoryLeaks: memory leak\n" );
00174 trial( LALFree( p ), 0, "" );
00175 trial( LALCheckMemoryLeaks(), 0, "" );
00176
00177 lalDebugLevel &= ~LALNMEMPAD;
00178 lalDebugLevel |= LALNMEMTRK;
00179 trial( p = LALMalloc( 1024 * sizeof( *p ) ), 0, "" );
00180 for ( i = 0; i < 1024; ++i ) p[i] = i;
00181 trial( q = LALCalloc( 1024, sizeof( *q ) ), 0, "" );
00182 for ( i = 0; i < 1024; ++i ) if ( q[i] ) die( memory not blanked );
00183 trial( p = LALRealloc( p, 4096 * sizeof( *p ) ), 0, "" );
00184 for ( i = 0; i < 1024; ++i ) if ( p[i] != i ) die( memory not copied );
00185 trial( q = LALRealloc( q, 0 ), 0, "" );
00186 if ( q ) die( memory not freed );
00187 trial( LALCheckMemoryLeaks(), SIGSEGV, "LALCheckMemoryLeaks: memory leak\n" );
00188 if ( *( p - 1 ) != (size_t)0xABadCafe ) die( wrong magic );
00189 if ( *( p - 2 ) != 4096 * sizeof( *p ) ) die( wrong size );
00190 trial( LALFree( p ), 0, "" );
00191 trial( LALCheckMemoryLeaks(), 0, "" );
00192
00193 lalDebugLevel |= LALNMEMDBG;
00194 trial( p = LALMalloc( 1024 * sizeof( *p ) ), 0, "" );
00195 for ( i = 0; i < 1024; ++i ) p[i] = i;
00196 trial( q = LALCalloc( 1024, sizeof( *q ) ), 0, "" );
00197 for ( i = 0; i < 1024; ++i ) if ( q[i] ) die( memory not blanked );
00198 trial( p = LALRealloc( p, 4096 * sizeof( *p ) ), 0, "" );
00199 for ( i = 0; i < 1024; ++i ) if ( p[i] != i ) die( memory not copied );
00200 trial( q = LALRealloc( q, 0 ), 0, "" );
00201
00202 trial( LALCheckMemoryLeaks(), 0, "" );
00203 trial( LALFree( p ), 0, "" );
00204 trial( LALCheckMemoryLeaks(), 0, "" );
00205
00206 lalDebugLevel = keep;
00207 return 0;
00208 }
00209
00210
00211
00212 static int testPadding( void )
00213 {
00214 int keep = lalDebugLevel;
00215
00216 lalDebugLevel |= LALNMEMTRK;
00217 lalDebugLevel &= ~( LALNMEMDBG | LALNMEMPAD );
00218
00219
00220 trial( LALFree( NULL ), SIGSEGV, "error: tried to free NULL pointer" );
00221
00222
00223 trial( p = LALMalloc( 2 * sizeof( *p ) ), 0, "" );
00224 p[-1] = 4;
00225 trial( LALFree( p ), SIGSEGV, "error: wrong magic" );
00226 p[-1] = 0xABadCafe;
00227 trial( LALFree( p ), 0, "" );
00228 trial( LALCheckMemoryLeaks(), 0, "" );
00229
00230
00231 trial( p = LALMalloc( 4 * sizeof( *p ) ), 0, "");
00232 n = p[-2];
00233 p[-2] = -1;
00234 trial( LALFree( p ), SIGSEGV, "error: corrupt size descriptor" );
00235 p[-2] = n;
00236 trial( LALFree( p ), 0, "" );
00237 trial( LALCheckMemoryLeaks(), 0, "" );
00238
00239
00240 trial( p = LALMalloc( 8 * sizeof( *p ) ), 0, "" );
00241 n = p[8];
00242 p[8] = 0;
00243 trial( LALFree( p ), SIGSEGV, "error: array bounds overwritten" );
00244 p[8] = n;
00245 trial( LALFree( p ), 0, "" );
00246 trial( LALCheckMemoryLeaks(), 0, "" );
00247
00248
00249 q = malloc( 4 * sizeof( *p ) );
00250 trial( p = LALMalloc( sizeof( *p ) ), 0, "" );
00251 memcpy( q, p - 2, 4 * sizeof( *p ) );
00252 trial( LALFree( p ), 0, "" );
00253 trial( LALFree( q + 2 ), SIGSEGV, "error: lalMallocTotal too small" );
00254 free( q );
00255 trial( LALCheckMemoryLeaks(), 0, "" );
00256
00257 lalDebugLevel = keep;
00258 return 0;
00259 }
00260
00261
00262 static int testAllocList( void )
00263 {
00264 int keep = lalDebugLevel;
00265
00266 s = malloc( sizeof( *s ) );
00267
00268 lalDebugLevel |= LALNMEMPAD;
00269 lalDebugLevel &= ~( LALNMEMDBG | LALNMEMTRK );
00270
00271
00272 trial( LALCheckMemoryLeaks(), 0, "" );
00273 trial( LALFree( s ), SIGSEGV, "not found" );
00274
00275
00276 trial( p = LALMalloc( 2 * sizeof( *p ) ), 0, "" );
00277 trial( q = LALMalloc( 4 * sizeof( *q ) ), 0, "" );
00278 trial( r = LALMalloc( 8 * sizeof( *r ) ), 0, "" );
00279 trial( LALFree( s ), SIGSEGV, "not found" );
00280 trial( LALFree( p ), 0, "" );
00281 trial( LALFree( r ), 0, "" );
00282 trial( LALCheckMemoryLeaks(), SIGSEGV, "memory leak" );
00283 trial( LALFree( q ), 0, "" );
00284 trial( LALCheckMemoryLeaks(), 0, "" );
00285
00286
00287 trial( s = LALRealloc( s, 1024 ), SIGSEGV, "not found" );
00288 trial( p = LALRealloc( NULL, 2 * sizeof( *p ) ), 0, "" );
00289
00290 trial( LALFree( p ), 0, "" );
00291 trial( LALCheckMemoryLeaks(), 0, "" );
00292
00293 free( s );
00294 lalDebugLevel = keep;
00295 return 0;
00296 }
00297
00298
00299 static int stressTestRealloc( void )
00300 {
00301 const size_t nmax = 256;
00302 int keep = lalDebugLevel;
00303
00304 v = NULL;
00305
00306 lalDebugLevel &= ~( LALMEMINFO | LALNMEMDBG | LALNMEMPAD | LALNMEMTRK );
00307
00308
00309 for ( n = 1; n <= nmax; ++n )
00310 {
00311 size_t *u;
00312 trial( v = LALRealloc( v, n * sizeof( *v ) ), 0, "" );
00313 trial( u = v[n - 1] = LALRealloc( NULL, n * sizeof( **v ) ), 0, "" );
00314 for ( i = 0; i < n; ++i ) u[i] = n - 1;
00315 for ( i = 0; i < n; ++i )
00316 {
00317 trial( u = v[i] = LALRealloc( v[i], n * sizeof( *u ) ), 0, "" );
00318 for ( j = 0; j < n - 1; ++j )
00319 if ( u[j] != n - 1 ) die( wrong contents );
00320 for ( j = 0; j < n; ++j )
00321 u[j] = n;
00322 }
00323 }
00324
00325 for ( n = 0; n < nmax; ++n )
00326 {
00327 trial( v[n] = LALRealloc( v[n], 0 ), 0, "" );
00328 }
00329 trial( v = LALRealloc( v, 0 ), 0, "" );
00330
00331 trial( LALCheckMemoryLeaks(), 0, "" );
00332 lalDebugLevel = keep;
00333 return 0;
00334 }
00335
00336
00337 int main( void )
00338 {
00339 #if defined(NDEBUG) || defined(LAL_NDEBUG)
00340 return 77;
00341 #else
00342
00343 setvbuf( mystderr = stdout, NULL, _IONBF, 0 );
00344 freopen( "/dev/null", "w", stderr );
00345
00346 lalRaiseHook = TestRaise;
00347
00348 if ( lalNoDebug )
00349 return 77;
00350
00351 if ( testOK() ) return 1;
00352 if ( testPadding() ) return 1;
00353 if ( testAllocList() ) return 1;
00354 if ( stressTestRealloc() ) return 1;
00355
00356 trial( LALCheckMemoryLeaks(), 0, "" );
00357
00358 return 0;
00359 #endif
00360 }