mirror of https://gitee.com/bigwinds/arangodb
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:
parent
3fc862f0ef
commit
ac277648f3
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue