Branch data Line data Source code
1 : : #include "moab/ErrorHandler.hpp"
2 : : #include "ErrorOutput.hpp"
3 : : #ifdef MOAB_HAVE_MPI
4 : : #include "moab_mpi.h"
5 : : #endif
6 : :
7 : : #include <stdlib.h>
8 : : #include <assert.h>
9 : :
10 : : #ifdef _WIN32
11 : : #include <io.h>
12 : : #include <windows.h>
13 : : namespace
14 : : {
15 : : void sleep( int sec )
16 : : {
17 : : Sleep( sec * 1000 );
18 : : }
19 : : } // namespace
20 : : #else
21 : : #include <unistd.h>
22 : : #endif
23 : :
24 : : namespace moab
25 : : {
26 : :
27 : : static ErrorOutput* errorOutput = NULL;
28 [ + - ]: 57 : static std::string lastError = "No error";
29 : :
30 : 335 : void MBErrorHandler_Init()
31 : : {
32 [ + - ]: 335 : if( NULL == errorOutput )
33 : : {
34 [ + - ][ + - ]: 335 : errorOutput = new( std::nothrow ) ErrorOutput( stderr );
35 [ - + ]: 335 : assert( NULL != errorOutput );
36 : 335 : errorOutput->use_world_rank();
37 : : }
38 : 335 : }
39 : :
40 : 332 : void MBErrorHandler_Finalize()
41 : : {
42 [ + - ]: 332 : if( NULL != errorOutput )
43 : : {
44 [ + - ]: 332 : delete errorOutput;
45 : 332 : errorOutput = NULL;
46 : : }
47 : 332 : }
48 : :
49 : 372 : bool MBErrorHandler_Initialized()
50 : : {
51 : 372 : return ( NULL != errorOutput );
52 : : }
53 : :
54 : 0 : void MBErrorHandler_GetLastError( std::string& error )
55 : : {
56 : 0 : error = lastError;
57 : 0 : }
58 : :
59 : 44 : void MBTraceBackErrorHandler( int line, const char* func, const char* file, const char* dir, const char* err_msg,
60 : : ErrorType err_type )
61 : : {
62 [ - + ]: 44 : if( NULL == errorOutput ) return;
63 : :
64 : : // For a globally fatal error, get world rank of current processor, so that it is only printed
65 : : // from processor 0 For a per-processor relevant error, set rank of current processor to 0, so
66 : : // that it is always printed
67 : 44 : int rank = 0;
68 [ + + ][ + - ]: 44 : if( MB_ERROR_TYPE_NEW_GLOBAL == err_type && errorOutput->have_rank() ) rank = errorOutput->get_rank();
[ + + ]
69 : :
70 [ + - ]: 44 : if( 0 == rank )
71 : : {
72 : : // Print the error message for a new error
73 [ + + ][ + - ]: 44 : if( MB_ERROR_TYPE_EXISTING != err_type && NULL != err_msg )
74 : : {
75 : 26 : errorOutput->print( "--------------------- Error Message ------------------------------------\n" );
76 : 26 : errorOutput->printf( "%s!\n", err_msg );
77 : 26 : lastError = err_msg;
78 : : }
79 : :
80 : : // Print a line of stack trace for a new error, or an existing one
81 : 44 : errorOutput->printf( "%s() line %d in %s%s\n", func, line, dir, file );
82 : : }
83 : : else
84 : : {
85 : : // Do not print the error message or stack trace, since processor 0 will print them
86 : : // Sleep 10 seconds before aborting so it will not accidently kill process 0
87 : 0 : sleep( 10 );
88 : 0 : abort();
89 : : }
90 : : }
91 : :
92 : 21736 : ErrorCode MBError( int line, const char* func, const char* file, const char* dir, ErrorCode err_code,
93 : : const char* err_msg, ErrorType err_type )
94 : : {
95 : : // When this routine is called to handle an existing error (instead of creating a new one),
96 : : // we need to check if the returned non-success result from a function might be a non-error
97 : : // condition. If no last error message was ever set, just return the given error code.
98 [ + + ][ + + ]: 21736 : if( MB_ERROR_TYPE_EXISTING == err_type && "No error" == lastError ) return err_code;
[ + + ]
99 : :
100 : 44 : MBTraceBackErrorHandler( line, func, file, dir, err_msg, err_type );
101 : :
102 : : #ifdef MOAB_HAVE_MPI
103 : : // If this is called from the main() routine we call MPI_Abort() to allow
104 : : // the parallel program to be properly shutdown
105 [ - + ]: 44 : if( strncmp( func, "main", 4 ) == 0 ) MPI_Abort( MPI_COMM_WORLD, err_code );
106 : : #endif
107 : :
108 : 44 : return err_code;
109 : : }
110 : :
111 [ + - ][ + - ]: 228 : } // namespace moab
|