MOAB: Mesh Oriented datABase  (version 5.4.0)
ErrorHandler.cpp
Go to the documentation of this file.
00001 #include "moab/ErrorHandler.hpp"
00002 #include "ErrorOutput.hpp"
00003 #ifdef MOAB_HAVE_MPI
00004 #include "moab_mpi.h"
00005 #endif
00006 
00007 #include <cstdlib>
00008 #include <cassert>
00009 
00010 #ifdef _WIN32
00011 #include <io.h>
00012 #include <windows.h>
00013 namespace
00014 {
00015 void sleep( int sec )
00016 {
00017     Sleep( sec * 1000 );
00018 }
00019 }  // namespace
00020 #else
00021 #include <unistd.h>
00022 #endif
00023 
00024 namespace moab
00025 {
00026 
00027 static ErrorOutput* errorOutput = NULL;
00028 static std::string lastError    = "No error";
00029 
00030 void MBErrorHandler_Init()
00031 {
00032     if( NULL == errorOutput )
00033     {
00034         errorOutput = new( std::nothrow ) ErrorOutput( stderr );
00035         assert( NULL != errorOutput );
00036         errorOutput->use_world_rank();
00037     }
00038 }
00039 
00040 void MBErrorHandler_Finalize()
00041 {
00042     if( NULL != errorOutput )
00043     {
00044         delete errorOutput;
00045         errorOutput = NULL;
00046     }
00047 }
00048 
00049 bool MBErrorHandler_Initialized()
00050 {
00051     return ( NULL != errorOutput );
00052 }
00053 
00054 void MBErrorHandler_GetLastError( std::string& error )
00055 {
00056     error = lastError;
00057 }
00058 
00059 void MBTraceBackErrorHandler( int line,
00060                               const char* func,
00061                               const char* file,
00062                               const char* dir,
00063                               const char* err_msg,
00064                               ErrorType err_type )
00065 {
00066     if( NULL == errorOutput ) return;
00067 
00068     // For a globally fatal error, get world rank of current processor, so that it is only printed
00069     // from processor 0 For a per-processor relevant error, set rank of current processor to 0, so
00070     // that it is always printed
00071     int rank = 0;
00072     if( MB_ERROR_TYPE_NEW_GLOBAL == err_type && errorOutput->have_rank() ) rank = errorOutput->get_rank();
00073 
00074     if( 0 == rank )
00075     {
00076         // Print the error message for a new error
00077         if( MB_ERROR_TYPE_EXISTING != err_type && NULL != err_msg )
00078         {
00079             errorOutput->print( "--------------------- Error Message ------------------------------------\n" );
00080             errorOutput->printf( "%s!\n", err_msg );
00081             lastError = err_msg;
00082         }
00083 
00084         // Print a line of stack trace for a new error, or an existing one
00085         errorOutput->printf( "%s() line %d in %s%s\n", func, line, dir, file );
00086     }
00087     else
00088     {
00089         // Do not print the error message or stack trace, since processor 0 will print them
00090         // Sleep 10 seconds before aborting so it will not accidently kill process 0
00091         sleep( 10 );
00092         abort();
00093     }
00094 }
00095 
00096 ErrorCode MBError( int line,
00097                    const char* func,
00098                    const char* file,
00099                    const char* dir,
00100                    ErrorCode err_code,
00101                    const char* err_msg,
00102                    ErrorType err_type )
00103 {
00104     // When this routine is called to handle an existing error (instead of creating a new one),
00105     // we need to check if the returned non-success result from a function might be a non-error
00106     // condition. If no last error message was ever set, just return the given error code.
00107     if( MB_ERROR_TYPE_EXISTING == err_type && "No error" == lastError ) return err_code;
00108 
00109     MBTraceBackErrorHandler( line, func, file, dir, err_msg, err_type );
00110 
00111 #ifdef MOAB_HAVE_MPI
00112     // If this is called from the main() routine we call MPI_Abort() to allow
00113     // the parallel program to be properly shutdown
00114     if( strncmp( func, "main", 4 ) == 0 ) MPI_Abort( MPI_COMM_WORLD, err_code );
00115 #endif
00116 
00117     return err_code;
00118 }
00119 
00120 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines