1
0
Fork 0

Change the way windows eventlogging is handled: initialize it once on start.

Fix unhandled exception handler to do less resource allocation.
This commit is contained in:
Wilfried Goesgens 2016-01-26 16:50:19 +01:00
parent 3fc862f0ef
commit ac277648f3
4 changed files with 70 additions and 19 deletions

View File

@ -70,6 +70,9 @@ static std::string FriendlyServiceName = "ArangoDB - the multi-model database";
static SERVICE_STATUS_HANDLE ServiceStatus;
// So we have a valid minidump area during startup:
static std::string miniDumpFilename = "c:\\arangodpanic.dmp";
void TRI_GlobalEntryFunction();
void TRI_GlobalExitFunction(int, void*);
@ -460,28 +463,23 @@ LONG CALLBACK unhandledExceptionHandler(EXCEPTION_POINTERS* e) {
#if HAVE_BACKTRACE
if ((e != nullptr) && (e->ExceptionRecord != nullptr)) {
LOG_ERROR("Unhandled exception: %d",
LOG_FATAL_WINDOWS("Unhandled exception: %d",
(int)e->ExceptionRecord->ExceptionCode);
} else {
LOG_ERROR("Unhandled exception witout ExceptionCode!");
LOG_FATAL_WINDOWS("Unhandled exception without ExceptionCode!");
}
std::string bt;
TRI_GetBacktrace(bt);
std::cout << bt << std::endl;
LOG_ERROR(bt.c_str());
LOG_FATAL_WINDOWS(bt.c_str());
std::string miniDumpFilename = TRI_GetTempPath();
miniDumpFilename +=
"\\minidump_" + std::to_string(GetCurrentProcessId()) + ".dmp";
LOG_ERROR("writing minidump: %s", miniDumpFilename.c_str());
HANDLE hFile =
CreateFile(miniDumpFilename.c_str(), GENERIC_WRITE, FILE_SHARE_READ, 0,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE) {
LOG_ERROR("could not open minidump file : %lu", GetLastError());
LOG_FATAL_WINDOWS("could not open minidump file : %lu", GetLastError());
return EXCEPTION_CONTINUE_SEARCH;
}
@ -499,12 +497,13 @@ LONG CALLBACK unhandledExceptionHandler(EXCEPTION_POINTERS* e) {
CloseHandle(hFile);
hFile = nullptr;
}
LOG_FATAL_WINDOWS("wrote minidump: %s", miniDumpFilename.c_str());
#endif
if ((e != nullptr) && (e->ExceptionRecord != nullptr)) {
LOG_ERROR("Unhandled exception: %d - will crash now.",
LOG_FATAL_WINDOWS("Unhandled exception: %d - will crash now.",
(int)e->ExceptionRecord->ExceptionCode);
} else {
LOG_ERROR("Unhandled exception without ExceptionCode - will crash now.!");
LOG_FATAL_WINDOWS("Unhandled exception without ExceptionCode - will crash now.!");
}
return EXCEPTION_CONTINUE_SEARCH;
}
@ -601,6 +600,11 @@ class WindowsArangoServer : public ArangoServer {
public:
WindowsArangoServer(int argc, char** argv) : ArangoServer(argc, argv) {
_progress = 2;
miniDumpFilename = TRI_GetTempPath();
miniDumpFilename +=
"\\minidump_" + std::to_string(GetCurrentProcessId()) + ".dmp";
}
};
@ -608,6 +612,9 @@ static int ARGC;
static char** ARGV;
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR* lpszArgv) {
if (!TRI_InitWindowsEventLog()) {
return ;
}
// register the service ctrl handler, lpszArgv[0] contains service name
ServiceStatus =
RegisterServiceCtrlHandlerA(lpszArgv[0], (LPHANDLER_FUNCTION)ServiceCtrl);
@ -618,11 +625,13 @@ static void WINAPI ServiceMain(DWORD dwArgc, LPSTR* lpszArgv) {
IsRunning = true;
ArangoInstance = new WindowsArangoServer(ARGC, ARGV);
ArangoInstance->setMode(rest::AnyServer::ServerMode::MODE_SERVICE);
ArangoInstance->start();
IsRunning = false;
// service has stopped
SetServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0);
TRI_CloseWindowsEventlog();
}
////////////////////////////////////////////////////////////////////////////////
@ -636,6 +645,12 @@ bool TRI_ParseMoreArgs(int argc, char* argv[]) {
/// this is slower than valgrind:
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF );
#endif
if (!TRI_InitWindowsEventLog()) {
std::cout << "failed to open windows event log!" << std::endl;
exit(1);
}
if (1 < argc) {
if (TRI_EqualString(argv[1], "--install-service")) {
InstallService(argc, argv);

View File

@ -2430,6 +2430,10 @@ int main(int argc, char* args[]) {
if (getenv("SHELL") != nullptr) {
cygwinShell = true;
}
if (!TRI_InitWindowsEventLog()) {
std::cerr << "failed to init event log" << std::endl;
return EXIT_FAILURE;
}
#endif
LocalEntryFunction();

View File

@ -508,13 +508,13 @@ int TRI_MapSystemError(DWORD error) {
static HANDLE hEventLog = INVALID_HANDLE_VALUE;
int TRI_InitWindowsEventLog(void) {
bool TRI_InitWindowsEventLog(void) {
hEventLog = RegisterEventSource(NULL, "ArangoDB");
if (NULL == hEventLog) {
// well, fail then.
return 0;
return false;
}
return 1;
return true;
}
void TRI_CloseWindowsEventlog(void) {
@ -538,11 +538,9 @@ void TRI_LogWindowsEventlog(char const* func, char const* file, int line,
char buf[1024];
char linebuf[32];
LPCSTR logBuffers[] = {buf, file, func, linebuf, NULL};
TRI_ASSERT(hEventLog != INVALID_HANDLE_VALUE);
if (!TRI_InitWindowsEventLog()) {
return;
}
snprintf(linebuf, sizeof(linebuf), "%d", line);
DWORD len = _vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
@ -555,7 +553,17 @@ void TRI_LogWindowsEventlog(char const* func, char const* file, int line,
// well, fail then...
}
TRI_CloseWindowsEventlog();
}
void TRI_WindowsEmergencyLog(char const* func,
char const* file, int line,
char const* fmt, ...) {
va_list ap;
va_start(ap, fmt);
va_list wva;
va_copy(wva, ap);
TRI_LogWindowsEventlog(func, file, line, fmt, ap);
va_end(wva);
}

View File

@ -97,6 +97,13 @@ void TRI_FixIcuDataEnv();
int TRI_MapSystemError(DWORD);
////////////////////////////////////////////////////////////////////////////////
/// @brief open/close the windows eventlog. Call on start / shutdown
////////////////////////////////////////////////////////////////////////////////
bool TRI_InitWindowsEventLog(void);
void TRI_CloseWindowsEventlog(void);
////////////////////////////////////////////////////////////////////////////////
/// @brief logs a message to the windows event log.
/// we rather are keen on logging something at all then on being able to work
@ -107,6 +114,23 @@ int TRI_MapSystemError(DWORD);
void TRI_LogWindowsEventlog(char const* func, char const* file, int line,
char const* fmt, va_list ap);
////////////////////////////////////////////////////////////////////////////////
/// @brief logs a message to the windows event log.
/// this wrapper (and the macro) are similar to regular log facilities.
/// they should however only be used in panic situations.
////////////////////////////////////////////////////////////////////////////////
void TRI_WindowsEmergencyLog(char const* func,
char const* file, int line,
char const* fmt, ...);
#define LOG_FATAL_WINDOWS(...) \
do { \
LOG_ARG_CHECK(__VA_ARGS__); \
TRI_WindowsEmergencyLog(__FUNCTION__, __FILE__, __LINE__, \
__VA_ARGS__); \
} while (0)
#endif