1#include"moab/ErrorHandler.hpp"2#include"ErrorOutput.hpp"3#ifdef MOAB_HAVE_MPI4#include"moab_mpi.h"5#endif67#include<cstdlib>8#include<cassert>910#ifdef _WIN3211#include<io.h>12#include<windows.h>13namespace14 {
15voidsleep( int sec )
16 {
17Sleep( sec * 1000 );
18 }
19 } // namespace20#else21#include<unistd.h>22#endif2324namespace moab
25 {
2627static ErrorOutput* errorOutput = NULL;
28static std::string lastError = "No error";
2930voidMBErrorHandler_Init()
31 {
32if( NULL == errorOutput )
33 {
34 errorOutput = new( std::nothrow ) ErrorOutput( stderr );
35assert( NULL != errorOutput );
36 errorOutput->use_world_rank();
37 }
38 }
3940voidMBErrorHandler_Finalize()
41 {
42if( NULL != errorOutput )
43 {
44delete errorOutput;
45 errorOutput = NULL;
46 }
47 }
4849boolMBErrorHandler_Initialized()
50 {
51return ( NULL != errorOutput );
52 }
5354voidMBErrorHandler_GetLastError( std::string& error )
55 {
56 error = lastError;
57 }
5859voidMBTraceBackErrorHandler( int line,
60constchar* func,
61constchar* file,
62constchar* dir,
63constchar* err_msg,
64 ErrorType err_type )
65 {
66if( NULL == errorOutput ) return;
6768// For a globally fatal error, get world rank of current processor, so that it is only printed69// from processor 0 For a per-processor relevant error, set rank of current processor to 0, so70// that it is always printed71int rank = 0;
72if( MB_ERROR_TYPE_NEW_GLOBAL == err_type && errorOutput->have_rank() ) rank = errorOutput->get_rank();
7374if( 0 == rank )
75 {
76// Print the error message for a new error77if( MB_ERROR_TYPE_EXISTING != err_type && NULL != err_msg )
78 {
79 errorOutput->print( "--------------------- Error Message ------------------------------------\n" );
80 errorOutput->printf( "%s!\n", err_msg );
81 lastError = err_msg;
82 }
8384// Print a line of stack trace for a new error, or an existing one85 errorOutput->printf( "%s() line %d in %s%s\n", func, line, dir, file );
86 }
87else88 {
89// Do not print the error message or stack trace, since processor 0 will print them90// Sleep 10 seconds before aborting so it will not accidently kill process 091sleep( 10 );
92abort();
93 }
94 }
9596ErrorCode MBError( int line,
97constchar* func,
98constchar* file,
99constchar* dir,
100 ErrorCode err_code,
101constchar* err_msg,
102 ErrorType err_type )
103 {
104// When this routine is called to handle an existing error (instead of creating a new one),105// we need to check if the returned non-success result from a function might be a non-error106// condition. If no last error message was ever set, just return the given error code.107if( MB_ERROR_TYPE_EXISTING == err_type && "No error" == lastError ) return err_code;
108109MBTraceBackErrorHandler( line, func, file, dir, err_msg, err_type );
110111#ifdef MOAB_HAVE_MPI112// If this is called from the main() routine we call MPI_Abort() to allow113// the parallel program to be properly shutdown114if( strncmp( func, "main", 4 ) == 0 ) MPI_Abort( MPI_COMM_WORLD, err_code );
115#endif116117return err_code;
118 }
119120 } // namespace moab