![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #include "moab/ErrorHandler.hpp"
00002 #include "ErrorOutput.hpp"
00003 #ifdef MOAB_HAVE_MPI
00004 #include "moab_mpi.h"
00005 #endif
00006
00007 #include
00008 #include
00009
00010 #ifdef _WIN32
00011 #include
00012 #include
00013 namespace
00014 {
00015 void sleep( int sec )
00016 {
00017 Sleep( sec * 1000 );
00018 }
00019 } // namespace
00020 #else
00021 #include
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