• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/maloc/tools/tests/zfence/eftest.c

00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <unistd.h>
00005 #include <setjmp.h>
00006 #include <signal.h>
00007 
00008 #include <efence.h>
00009 
00010 /*
00011  * Electric Fence confidence tests.
00012  * Make sure all of the various functions of Electric Fence work correctly.
00013  */
00014 
00015 #ifndef    PAGE_PROTECTION_VIOLATED_SIGNAL
00016 #define    PAGE_PROTECTION_VIOLATED_SIGNAL  SIGSEGV
00017 #endif
00018 
00019 struct diagnostic {
00020            int                   (*test)(void);
00021            int                   expectedStatus;
00022            const char *          explanation;
00023 };
00024 
00025 extern int EF_PROTECT_BELOW;
00026 extern int EF_ALIGNMENT;
00027 
00028 static jmp_buf        env;
00029 
00030 /*
00031  * There is still too little standardization of the arguments and return
00032  * type of signal handler functions.
00033  */
00034 static
00035 void
00036 segmentationFaultHandler(
00037 int signalNumber
00038 #if ( defined(_AIX) )
00039 , ...
00040 #endif
00041 )
00042  {
00043            signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
00044            longjmp(env, 1);
00045 }
00046 
00047 static int
00048 gotSegmentationFault(int (*test)(void))
00049 {
00050            if ( setjmp(env) == 0 ) {
00051                       int                              status;
00052 
00053                       signal(PAGE_PROTECTION_VIOLATED_SIGNAL
00054                       ,segmentationFaultHandler);
00055                       status = (*test)();
00056                       signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
00057                       return status;
00058            }
00059            else
00060                       return 1;
00061 }
00062 
00063 static char *         allocation;
00064 /* c is global so that assignments to it won't be optimized out. */
00065 char       c;
00066 
00067 static int
00068 testSizes(void)
00069 {
00070            /*
00071             * If ef_number can't hold all of the bits of a void *, have the user
00072             * add -DUSE_ LONG_LONG to the compiler flags so that ef_number will be
00073             * declared as "unsigned long long" instead of "unsigned long".
00074             */
00075            return ( sizeof(ef_number) < sizeof(void *) );
00076 }
00077 
00078 static int
00079 allocateMemory(void)
00080 {
00081            allocation = (char *)malloc(1);
00082 
00083            if ( allocation != 0 )
00084                       return 0;
00085            else
00086                       return 1;
00087 }
00088 
00089 static int
00090 freeMemory(void)
00091 {
00092            free(allocation);
00093            return 0;
00094 }
00095 
00096 static int
00097 protectBelow(void)
00098 {
00099            EF_PROTECT_BELOW = 1;
00100            return 0;
00101 }
00102 
00103 static int
00104 read0(void)
00105 {
00106            c = *allocation;
00107 
00108            return 0;
00109 }
00110 
00111 static int
00112 write0(void)
00113 {
00114            *allocation = 1;
00115 
00116            return 0;
00117 }
00118 
00119 static int
00120 read1(void)
00121 {
00122            c = allocation[1];
00123 
00124            return 0;
00125 }
00126 
00127 static int
00128 readMinus1(void)
00129 {
00130            c = allocation[-1];
00131            return 0;
00132 }
00133 
00134 static struct diagnostic diagnostics[] = {
00135            {
00136                       testSizes, 0,
00137                       "Please add -DLONG_LONG to the compiler flags and recompile."
00138            },
00139            {
00140                       allocateMemory, 0,
00141                       "Allocation 1: This test allocates a single byte of memory."
00142            },
00143            {
00144                       read0, 0,
00145                       "Read valid memory 1: This test reads the allocated memory."
00146            },
00147            {
00148                       write0, 0,
00149                       "Write valid memory 1: This test writes the allocated memory."
00150            },
00151            {
00152                       read1, 1,
00153                       "Read overrun: This test reads beyond the end of the buffer."
00154            },
00155            {
00156                       freeMemory, 0,
00157                       "Free memory: This test frees the allocated memory."
00158            },
00159            {
00160                       protectBelow, 0,
00161                       "Protect below: This sets Electric Fence to protect\n"
00162                       "the lower boundary of a malloc buffer, rather than the\n"
00163                       "upper boundary."
00164            },
00165            {
00166                       allocateMemory, 0,
00167                       "Allocation 2: This allocates memory with the lower boundary"
00168                       " protected."
00169            },
00170            {
00171                       read0, 0,
00172                       "Read valid memory 2: This test reads the allocated memory."
00173            },
00174            {
00175                       write0, 0,
00176                       "Write valid memory 2: This test writes the allocated memory."
00177            },
00178            {
00179                       readMinus1, 1,
00180                       "Read underrun: This test reads before the beginning of the"
00181                       " buffer."
00182            },
00183            {
00184                       0, 0, 0
00185            }
00186 };
00187 
00188 static const char     failedTest[]
00189  = "Electric Fence confidence test failed.\n";
00190 
00191 static const char     newline = '\n';
00192 
00193 int
00194 main(int argc, char * * argv)
00195 {
00196            static const struct diagnostic * diag = diagnostics;
00197            
00198 
00199            EF_PROTECT_BELOW = 0;
00200            EF_ALIGNMENT = 0;
00201 
00202            while ( diag->explanation != 0 ) {
00203                       int        status = gotSegmentationFault(diag->test);
00204 
00205                       if ( status != diag->expectedStatus ) {
00206                                  /*
00207                                   * Don't use stdio to print here, because stdio
00208                                   * uses malloc() and we've just proven that malloc()
00209                                   * is broken. Also, use _exit() instead of exit(),
00210                                   * because _exit() doesn't flush stdio.
00211                                   */
00212                                  write(2, failedTest, sizeof(failedTest) - 1);
00213                                  write(2, diag->explanation, strlen(diag->explanation));
00214                                  write(2, &newline, 1);
00215                                  _exit(-1);
00216                       }
00217                       diag++;
00218            }
00219            return 0;
00220 }

Generated on Wed Oct 20 2010 11:12:15 for APBS by  doxygen 1.7.2