diff --git a/db/db.cpp b/db/db.cpp index 01a61ad07c4..f7d1a4a4f79 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -24,6 +24,7 @@ #include "../util/unittest.h" #include "../util/file_allocator.h" #include "../util/background.h" +#include "../util/text.h" #include "dbmessage.h" #include "instance.h" #include "clientcursor.h" @@ -1045,7 +1046,7 @@ namespace mongo { void myterminate() { rawOut( "terminate() called, printing stack:" ); printStackTrace(); - abort(); + ::abort(); } void setupSignals_ignoreHelper( int signal ) {} @@ -1114,19 +1115,67 @@ namespace mongo { } } + LPTOP_LEVEL_EXCEPTION_FILTER filtLast = 0; + ::HANDLE standardOut = GetStdHandle(STD_OUTPUT_HANDLE); + LONG WINAPI exceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo) { + { + // given the severity of the event we write to console in addition to the --logFile + // (rawOut writes to the logfile, if a special one were specified) + DWORD written; + WriteFile(standardOut, "unhandled exception\n", 20, &written, 0); + FlushFileBuffers(standardOut); + } + + DWORD ec = ExceptionInfo->ExceptionRecord->ExceptionCode; + if( ec == EXCEPTION_ACCESS_VIOLATION ) { + rawOut("access violation"); + } + else { + rawOut("unhandled exception"); + char buf[64]; + strcpy(buf, "ec=0x"); + _ui64toa(ec, buf+5, 16); + rawOut(buf); + } + if( filtLast ) + return filtLast(ExceptionInfo); + return EXCEPTION_EXECUTE_HANDLER; + } + + // called by mongoAbort() + extern void (*reportEventToSystem)(const char *msg); + void reportEventToSystemImpl(const char *msg) { + static ::HANDLE hEventLog = RegisterEventSource( NULL, TEXT("mongod") ); + if( hEventLog ) { + std::wstring s = toNativeString(msg); + LPCTSTR txt = s.c_str(); + BOOL ok = ReportEvent( + hEventLog, EVENTLOG_ERROR_TYPE, + 0, 0, NULL, + 1, + 0, + &txt, + 0); + wassert(ok); + } + } + void myPurecallHandler() { - rawOut( "pure virtual method called, printing stack:" ); printStackTrace(); - abort(); + mongoAbort("pure virtual"); } void setupSignals( bool inFork ) { + reportEventToSystem = reportEventToSystemImpl; + filtLast = SetUnhandledExceptionFilter(exceptionFilter); + if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) ) ; else - massert( 10297 , "Couldn't register Windows Ctrl-C handler", false); + msgasserted( 10297 , "Couldn't register Windows Ctrl-C handler" ); _set_purecall_handler( myPurecallHandler ); } + #endif } // namespace mongo diff --git a/db/dur.cpp b/db/dur.cpp index 75538b32fe6..a7915286dab 100644 --- a/db/dur.cpp +++ b/db/dur.cpp @@ -516,19 +516,19 @@ namespace mongo { } catch(DBException& e ) { log() << "dbexception in groupCommitLL causing immediate shutdown: " << e.toString() << endl; - abort(); + mongoAbort("dur1"); } catch(std::ios_base::failure& e) { log() << "ios_base exception in groupCommitLL causing immediate shutdown: " << e.what() << endl; - abort(); + mongoAbort("dur2"); } catch(std::bad_alloc& e) { log() << "bad_alloc exception in groupCommitLL causing immediate shutdown: " << e.what() << endl; - abort(); + mongoAbort("dur3"); } catch(std::exception& e) { log() << "exception in dur::groupCommitLL causing immediate shutdown: " << e.what() << endl; - abort(); + mongoAbort("dur4"); } return false; } @@ -602,19 +602,19 @@ namespace mongo { } catch(DBException& e ) { log() << "dbexception in groupCommit causing immediate shutdown: " << e.toString() << endl; - abort(); + mongoAbort("gc1"); } catch(std::ios_base::failure& e) { log() << "ios_base exception in groupCommit causing immediate shutdown: " << e.what() << endl; - abort(); + mongoAbort("gc2"); } catch(std::bad_alloc& e) { log() << "bad_alloc exception in groupCommit causing immediate shutdown: " << e.what() << endl; - abort(); + mongoAbort("gc3"); } catch(std::exception& e) { log() << "exception in dur::groupCommit causing immediate shutdown: " << e.what() << endl; - abort(); // based on myTerminate() + mongoAbort("gc4"); } } @@ -695,7 +695,7 @@ namespace mongo { } catch(std::exception& e) { log() << "exception in durThread causing immediate shutdown: " << e.what() << endl; - abort(); // based on myTerminate() + mongoAbort("exception in durThread"); } } cc().shutdown(); diff --git a/db/dur.h b/db/dur.h index 5917e8e8e7e..93106ccc617 100644 --- a/db/dur.h +++ b/db/dur.h @@ -9,6 +9,9 @@ namespace mongo { class NamespaceDetails; + void mongoAbort(const char *msg); + void abort(); // not defined -- use mongoAbort() instead + namespace dur { // a smaller limit is likely better on 32 bit diff --git a/db/instance.cpp b/db/instance.cpp index 51604f7203e..f1022f0d606 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -220,6 +220,15 @@ namespace mongo { return ok; } + void (*reportEventToSystem)(const char *msg) = 0; + + void mongoAbort(const char *msg) { + if( reportEventToSystem ) + reportEventToSystem(msg); + rawOut(msg); + ::abort(); + } + // Returns false when request includes 'end' void assembleResponse( Message &m, DbResponse &dbresponse, const HostAndPort& remote ) { @@ -755,7 +764,7 @@ namespace mongo { } if( --n <= 0 ) { log() << "shutdown: couldn't acquire write lock, aborting" << endl; - abort(); + mongoAbort("couldn't acquire write lock"); } log() << "shutdown: waiting for write lock..." << endl; } diff --git a/dbtests/framework.cpp b/dbtests/framework.cpp index bb96279d97a..92b40e4fd5f 100644 --- a/dbtests/framework.cpp +++ b/dbtests/framework.cpp @@ -170,7 +170,7 @@ namespace mongo { if (minutesRunning > 30){ log() << currentTestName << " has been running for more than 30 minutes. aborting." << endl; - abort(); + ::abort(); } else if (minutesRunning > 1){ warning() << currentTestName << " has been running for more than " << minutesRunning-1 << " minutes." << endl; @@ -422,4 +422,5 @@ namespace mongo { } void setupSignals( bool inFork ) {} + } diff --git a/tools/restore.cpp b/tools/restore.cpp index 9a18c00e93a..4f1e5968632 100644 --- a/tools/restore.cpp +++ b/tools/restore.cpp @@ -257,7 +257,7 @@ public: cerr << "Error creating index " << o["ns"].String(); cerr << ": " << err["code"].Int() << " " << err["err"].String() << endl; cerr << "To resume index restoration, run " << _name << " on file" << _fileName << " manually." << endl; - abort(); + ::abort(); } } else { diff --git a/util/concurrency/race.h b/util/concurrency/race.h index 0b8338c4333..9080124f27c 100644 --- a/util/concurrency/race.h +++ b/util/concurrency/race.h @@ -27,7 +27,7 @@ namespace mongo { void fail() { log() << "synchronization (race condition) failure" << endl; printStackTrace(); - abort(); + ::abort(); } void enter() { if( ++n != 1 ) fail(); diff --git a/util/log.cpp b/util/log.cpp index eb7a848cabf..40cea136035 100644 --- a/util/log.cpp +++ b/util/log.cpp @@ -19,7 +19,6 @@ #include "pch.h" #include "assert_util.h" #include "assert.h" -//#include "file.h" #include using namespace std; @@ -28,7 +27,7 @@ using namespace std; #include #endif -#include "../db/jsobj.h" +//#include "../db/jsobj.h" namespace mongo { @@ -84,7 +83,7 @@ namespace mongo { if ( _file ) { #ifdef _WIN32 - cout << "log rotation doesn't work on windows" << endl; + cout << "log rotation net yet supported on windows" << endl; return; #else struct tm t; @@ -135,4 +134,3 @@ namespace mongo { FILE* Logstream::logfile = stdout; } - diff --git a/util/log.h b/util/log.h index de8969315f4..53fc0de7987 100644 --- a/util/log.h +++ b/util/log.h @@ -431,7 +431,6 @@ namespace mongo { string errnoWithPrefix( const char * prefix ); void Logstream::logLockless( const StringData& s ) { - if ( s.size() == 0 ) return;