[MOAB-dev] r1585 - MOAB/trunk

kraftche at mcs.anl.gov kraftche at mcs.anl.gov
Tue Feb 5 11:41:18 CST 2008


Author: kraftche
Date: 2008-02-05 11:41:18 -0600 (Tue, 05 Feb 2008)
New Revision: 1585

Modified:
   MOAB/trunk/TestUtil.hpp
Log:
Remove #include<setjmp.h>: should be withing a #ifdef, and was.

Add comments.



Modified: MOAB/trunk/TestUtil.hpp
===================================================================
--- MOAB/trunk/TestUtil.hpp	2008-02-05 17:17:26 UTC (rev 1584)
+++ MOAB/trunk/TestUtil.hpp	2008-02-05 17:41:18 UTC (rev 1585)
@@ -33,6 +33,10 @@
 // Use signal handler and long jumps to return error state to test runner.
 // Might be portable to Windows (not sure).  Possibly undefined behavior (e.g. continuing 
 // with next test after catching segfault is technically undefined behavior.)
+// Also, tests can corrupt heap memory management, interferring with later tests.
+// Leaks memory on test failure (no stack unwind).  This is actually a feature, as
+// we don't care too much about tests leaking memory and trying to reconver memory
+// might make things worse, depending on why the test failed.
 #define LONGJMP_MODE 3      
 
 // If test application hasn't set MODE, set to default
@@ -53,17 +57,29 @@
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <setjmp.h>
 
+/***************************************************************************************
+ *                     Define What to do when a test fails.
+ ***************************************************************************************/
+
+// For EXCEPTION_MODE, throw an exception when a test fails.
+// This will unwind stack, recover memory, etc. 
 #if MODE == EXCEPTION_MODE
    struct ErrorExcept{};
 #  define FLAG_ERROR throw ErrorExcept()
+// For FORK_MODE, the test is running in its own processs.  Just
+// terminate the process with a non-zero exit code when the test
+// fails.
 #elif MODE == FORK_MODE
 #  include <sys/types.h>
 #  include <sys/wait.h>
 #  include <unistd.h>
 #  include <errno.h>
 #  define FLAG_ERROR exit(1)
+// For LONGJMP_MODE, we do a long jump to just before the test is
+// run, with a return value of -1 to indicate failures (positive
+// return codes are used if the test caused a segfault or other
+// signal.)
 #elif MODE == LONGJMP_MODE
 #  include <signal.h>
 #  include <setjmp.h>
@@ -72,9 +88,18 @@
 #  error "MODE not set"
 #endif
 
+/***************************************************************************************
+ *                              Setup for LONGJMP_MODE
+ ***************************************************************************************/
+
 #if MODE == LONGJMP_MODE
 
+// Variable to hold stack state for longjmp
 sigjmp_buf jmpenv;
+
+// Define signal handler used to catch errors such as segfaults.
+// Signal handler does longjmp with the signal number as the 
+// return value.
 extern "C" {
   void sighandler( int sig ) {
     signal( sig, sighandler );
@@ -84,15 +109,21 @@
   }
   typedef void (*sigfunc_t)(int);
 } // extern "C"
+
+// Helper function to register signal handlers.  
 int sethandler( int sig ) {
   sigfunc_t h = signal( sig, &sighandler );
   if (h == SIG_ERR)
     return  1;
+   // If user-defined signal handler (or signal is ignored),
+   // than unregister our handler.
   else if (h != SIG_DFL)
     signal( sig, h );
   return 0;
 }
 
+// Register signal handlers for all defined signals that typicall result
+// in process termination.
 int init_signal_handlers()
 {
   int result = 0;
@@ -147,13 +178,18 @@
   return result;
 }
 
-// initialize global to force call to init_signal_handlers
+// Declare a garbage global variable.  Use variable initialization to
+// force call to init_signal_handlers().  
 int junk_init_var = init_signal_handlers();
 
 #endif // LONGJMP_MODE
 
 
+/***************************************************************************************
+ *                            The Code to Run Tests
+ ***************************************************************************************/
 
+
 /* Make sure IS_BUILDING_MB is defined so we can include MBInternals.hpp */
 #include "MBTypes.h"
 #ifndef IS_BUILDING_MB
@@ -225,15 +261,25 @@
   }
   
 #elif MODE == LONGJMP_MODE
+    // Save stack state at this location.
   int rval = sigsetjmp( jmpenv, 1 );
+    // If rval is zero, then we haven't run the test yet. 
+    // If rval is non-zero then
+    // a) we ran the test
+    // b) the test failed
+    // c) we did a longjmp back to the location where we called setsigjmp.
+    
+    // run test
   if (!rval) {
     (*test)();
     return 0;
   }
+    // some check failed
   else if (rval == -1) {
     printf( "  %s: FAILED\n", func_name );
     return 1;
   }
+    // a signal was raised (e.g. segfault)
   else {
     printf( "  %s: TERMINATED (signal %d)\n", func_name, rval );
     return 1;
@@ -244,6 +290,12 @@
 }
 
 
+
+/***************************************************************************************
+ *                            CHECK_EQUAL implementations
+ ***************************************************************************************/
+
+// Common implementatation for most types
 #define EQUAL_TEST_IMPL( TEST, TYPE ) if( !(TEST) ) { \
   printf( "Equality Test Failed: %s == %s\n", sA, sB ); \
   printf( "  at line %d of '%s'\n", line, file ); \
@@ -296,6 +348,8 @@
 }
 
 
+// Special case for MBErrorCode, use mb_error_str() to print the 
+// string name of the error code.
 void check_equal( MBErrorCode A, MBErrorCode B, const char* sA, const char* sB, int line, const char* file )
 {
   if (A == B)




More information about the moab-dev mailing list