From fa6836d17a88dfe3122fdf96012268eda7b48a17 Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Mon, 26 Aug 2019 14:16:39 -0700 Subject: [PATCH] Added ability to generate Dump file on crash, on Windows --- meshconsole/main.c | 6 ++-- meshservice/ServiceMain.c | 22 ++++++------ microscript/ILibDuktape_ScriptContainer.c | 42 +++++++++++++++++++++-- microstack/ILibParsers.c | 29 ++++++++++++++-- microstack/ILibParsers.h | 13 +++++-- microstack/ILibProcessPipe.c | 6 ++-- 6 files changed, 94 insertions(+), 24 deletions(-) diff --git a/meshconsole/main.c b/meshconsole/main.c index 066ee50..f25d7b5 100644 --- a/meshconsole/main.c +++ b/meshconsole/main.c @@ -229,7 +229,7 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]); #ifdef WIN32 _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); // Set SIGNAL on windows to listen for Ctrl-C - CONTEXT winExceptionContext; + ILib_DumpEnabledContext winExceptionContext; #elif defined(_POSIX) signal(SIGPIPE, SIG_IGN); // Set a SIGNAL on Linux to listen for Ctrl-C signal(SIGINT, BreakSink);// Shutdown on Ctrl + C @@ -253,9 +253,9 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]); MeshAgent_Destroy(agentHost); agentHost = NULL; } - __except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winExceptionContext)) + __except (ILib_WindowsExceptionFilterEx(GetExceptionCode(), GetExceptionInformation(), &winExceptionContext)) { - ILib_WindowsExceptionDebug(&winExceptionContext); + ILib_WindowsExceptionDebugEx(&winExceptionContext); } wmain_free(argv); _CrtDumpMemoryLeaks(); diff --git a/meshservice/ServiceMain.c b/meshservice/ServiceMain.c index 2f43c9b..a15f452 100644 --- a/meshservice/ServiceMain.c +++ b/meshservice/ServiceMain.c @@ -279,7 +279,7 @@ void WINAPI RemoveUninstallIcon() void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) { - CONTEXT winException; + ILib_DumpEnabledContext winException; size_t len = 0; WCHAR str[_MAX_PATH]; @@ -325,9 +325,9 @@ void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) MeshAgent_Start(agent, g_serviceArgc, g_serviceArgv); agent = NULL; } - __except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winException)) + __except (ILib_WindowsExceptionFilterEx(GetExceptionCode(), GetExceptionInformation(), &winException)) { - ILib_WindowsExceptionDebug(&winException); + ILib_WindowsExceptionDebugEx(&winException); } CoUninitialize(); @@ -923,7 +923,7 @@ int wmain(int argc, char* wargv[]) char str2[_MAX_PATH]; char* proxyarg = NULL; char* tagarg = NULL; - CONTEXT winException; + ILib_DumpEnabledContext winException; int retCode = 0; int argvi, argvsz; @@ -1122,9 +1122,9 @@ int wmain(int argc, char* wargv[]) MeshAgent_Destroy(agent); agent = NULL; } - __except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winException)) + __except (ILib_WindowsExceptionFilterEx(GetExceptionCode(), GetExceptionInformation(), &winException)) { - ILib_WindowsExceptionDebug(&winException); + ILib_WindowsExceptionDebugEx(&winException); } wmain_free(argv); return(retCode); @@ -1413,9 +1413,9 @@ int wmain(int argc, char* wargv[]) MeshAgent_Destroy(agent); agent = NULL; } - __except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winException)) + __except (ILib_WindowsExceptionFilterEx(GetExceptionCode(), GetExceptionInformation(), &winException)) { - ILib_WindowsExceptionDebug(&winException); + ILib_WindowsExceptionDebugEx(&winException); } } else @@ -1534,7 +1534,7 @@ char* getMshSettings(char* fileName, char* selfexe, char** meshname, char** mesh // Start as a temporary mesh agent. DWORD WINAPI StartTempAgent(_In_ LPVOID lpParameter) { - CONTEXT winException; + ILib_DumpEnabledContext winException; char selfexe[_MAX_PATH]; char *selfexe_ptr[] = { selfexe }; WCHAR str[_MAX_PATH]; @@ -1605,9 +1605,9 @@ DWORD WINAPI StartTempAgent(_In_ LPVOID lpParameter) MeshAgent_Destroy(agent); agent = NULL; } - __except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winException)) + __except (ILib_WindowsExceptionFilterEx(GetExceptionCode(), GetExceptionInformation(), &winException)) { - ILib_WindowsExceptionDebug(&winException); + ILib_WindowsExceptionDebugEx(&winException); } CoUninitialize(); diff --git a/microscript/ILibDuktape_ScriptContainer.c b/microscript/ILibDuktape_ScriptContainer.c index 226acb5..7ce3234 100644 --- a/microscript/ILibDuktape_ScriptContainer.c +++ b/microscript/ILibDuktape_ScriptContainer.c @@ -93,11 +93,12 @@ char exeJavaScriptGuid[] = "B996015880544A19B7F7E9BE44914C18"; #define ILibDuktape_ScriptContainer_Settings_ExitHandler "\xFF_ScriptContainerSettings_ExitHandler" #define ILibDuktape_ScriptContainer_Settings_ExitUser "\xFF_ScriptContainerSettings_ExitUser" #define ILibDuktape_ScriptContainer_Process_ArgArray "\xFF_argArray" +#define ILibDuktape_ScriptContainer_Process_CoreDumpPath "\xFF_coreDumpPath" #define ILibDuktape_ScriptContainer_Process_Restart "\xFF_ScriptContainer_Process_Restart" #define ILibDuktape_ScriptContainer_Process_stdin "\xFF_stdin" #define ILibDuktape_ScriptContainer_Process_stdout "\xFF_stdout" #define ILibDuktape_ScriptContainer_Process_stderr "\xFF_stderr" -#define ILibDuktape_ScriptContainer_Signal_ListenerPtr "\xFF_signalListener" +#define ILibDuktape_ScriptContainer_Signal_ListenerPtr "\xFF_signalListener" #define ILibDuktape_ScriptContainer_ExitCode "\xFF_ExitCode" #define ILibDuktape_ScriptContainer_Exitting "\xFF_Exiting" @@ -943,6 +944,42 @@ duk_ret_t ILibDuktape_Process_setenv(duk_context *ctx) return(0); } +duk_ret_t ILibDuktape_ScriptContainer_Process_coreDumpLocation_getter(duk_context *ctx) +{ + if (g_ILibCrashDump_path == NULL) + { + duk_push_null(ctx); + } + else + { +#ifdef WIN32 + ILibDuktape_String_PushWideString(ctx, g_ILibCrashDump_path, 0); +#else + duk_push_string(ctx, g_ILibCrashDump_path); +#endif + } + return(1); +} +duk_ret_t ILibDuktape_ScriptContainer_Process_coreDumpLocation_setter(duk_context *ctx) +{ + if (duk_is_null(ctx, 0)) + { + g_ILibCrashDump_path = NULL; + duk_push_this(ctx); // [process] + duk_del_prop_string(ctx, -1, ILibDuktape_ScriptContainer_Process_CoreDumpPath); // [process] + duk_pop(ctx); // ... + } + else + { + duk_push_this(ctx); // [process] + ILibDuktape_String_UTF8ToWideEx(ctx, (char*)duk_require_string(ctx, 0)); // [process][path] + g_ILibCrashDump_path = Duktape_GetBuffer(ctx, -1, NULL); + duk_put_prop_string(ctx, -2, ILibDuktape_ScriptContainer_Process_CoreDumpPath); // [process] + duk_pop(ctx); // ... + } + return(0); +} + void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList) { int i = 0; @@ -957,7 +994,8 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList) ILibDuktape_CreateEventWithGetter(ctx, "env", ILibDuktape_ScriptContainer_Process_env); ILibDuktape_CreateInstanceMethod(ctx, "cwd", ILibDuktape_Process_cwd, 0); ILibDuktape_CreateInstanceMethod(ctx, "setenv", ILibDuktape_Process_setenv, 2); - + ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "coreDumpLocation", ILibDuktape_ScriptContainer_Process_coreDumpLocation_getter, ILibDuktape_ScriptContainer_Process_coreDumpLocation_setter); + duk_push_object(ctx); if (sslvS != ((char*)NULL + 1)) { diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index 4eecc21..4445ec3 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -2105,20 +2105,23 @@ ILibExportMethod void ILibChain_EndContinue(void *chain) } char* g_ILibCrashID = NULL; +char* g_ILibCrashDump_path = NULL; #if defined(WIN32) -int ILib_WindowsExceptionFilter(DWORD exceptionCode, void *exceptionInfo, CONTEXT *exceptionContext) +int ILib_WindowsExceptionFilterEx(DWORD exceptionCode, void *exceptionInfo, ILib_DumpEnabledContext *exceptionContext) { if (IsDebuggerPresent()) { return(EXCEPTION_CONTINUE_SEARCH); } if (exceptionCode == EXCEPTION_ACCESS_VIOLATION || exceptionCode == EXCEPTION_STACK_OVERFLOW || exceptionCode == EXCEPTION_INVALID_HANDLE) { - memcpy_s(exceptionContext, sizeof(CONTEXT), ((EXCEPTION_POINTERS*)exceptionInfo)->ContextRecord, sizeof(CONTEXT)); + exceptionContext->pctx = &(exceptionContext->ctx); exceptionContext->prec = &(exceptionContext->rec); + memcpy_s(exceptionContext->pctx, sizeof(CONTEXT), ((EXCEPTION_POINTERS*)exceptionInfo)->ContextRecord, sizeof(CONTEXT)); + memcpy_s(exceptionContext->prec, sizeof(EXCEPTION_RECORD), ((EXCEPTION_POINTERS*)exceptionInfo)->ExceptionRecord, sizeof(EXCEPTION_RECORD)); return(EXCEPTION_EXECUTE_HANDLER); } return(EXCEPTION_CONTINUE_SEARCH); } -void ILib_WindowsExceptionDebug(CONTEXT *exceptionContext) +void ILib_WindowsExceptionDebugEx(ILib_DumpEnabledContext *dumpEnabledExceptionContext) { char buffer[4096]; STACKFRAME64 StackFrame; @@ -2126,10 +2129,30 @@ void ILib_WindowsExceptionDebug(CONTEXT *exceptionContext) char imgBuffer[4096]; DWORD MachineType; int len = 0; + CONTEXT *exceptionContext = dumpEnabledExceptionContext->pctx; ZeroMemory(&StackFrame, sizeof(STACKFRAME64)); buffer[0] = 0; + if (g_ILibCrashDump_path != NULL) + { + HANDLE hDumpFile = CreateFileW(g_ILibCrashDump_path, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + MINIDUMP_EXCEPTION_INFORMATION i; + i.ClientPointers = FALSE; + i.ExceptionPointers = dumpEnabledExceptionContext; + i.ThreadId = GetCurrentThreadId(); + MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, + MiniDumpWithIndirectlyReferencedMemory | + MiniDumpWithPrivateReadWriteMemory | + MiniDumpWithDataSegs | + MiniDumpWithHandleData | + MiniDumpWithFullMemoryInfo | + MiniDumpWithThreadInfo | + MiniDumpWithUnloadedModules , &i, NULL, NULL); + CloseHandle(hDumpFile); + } + + #ifndef WIN64 MachineType = IMAGE_FILE_MACHINE_I386; StackFrame.AddrPC.Offset = exceptionContext->Eip; diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index 007a8ab..2885cdd 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -1382,9 +1382,18 @@ int ILibIsRunningOnChainThread(void* chain); void ILibChain_DebugOffset(char *buffer, int bufferLen, uint64_t addrOffset); char* ILibChain_Debug(void *chain, char* buffer, int bufferLen); extern char* g_ILibCrashID; + extern char* g_ILibCrashDump_path; + #if defined(WIN32) - int ILib_WindowsExceptionFilter(DWORD exceptionCode, void *exceptionInfo, CONTEXT *exceptionContext); - void ILib_WindowsExceptionDebug(CONTEXT *exceptionContext); + typedef struct ILib_DumpEnabledContext + { + PEXCEPTION_RECORD prec; + PCONTEXT pctx; + EXCEPTION_RECORD rec; + CONTEXT ctx; + }ILib_DumpEnabledContext; + int ILib_WindowsExceptionFilterEx(DWORD exceptionCode, void *exceptionInfo, ILib_DumpEnabledContext *dumpEnabledExceptionContext); + void ILib_WindowsExceptionDebugEx(ILib_DumpEnabledContext *dumpEnabledExceptionContext); #elif defined(_POSIX) char* ILib_POSIX_InstallCrashHandler(char *exename); #endif diff --git a/microstack/ILibProcessPipe.c b/microstack/ILibProcessPipe.c index 6e3ea53..2a20069 100644 --- a/microstack/ILibProcessPipe.c +++ b/microstack/ILibProcessPipe.c @@ -453,14 +453,14 @@ void ILibProcessPipe_Manager_WindowsRunLoopEx(void *arg) } ILibProcessPipe_Manager_WindowsRunLoop(void *arg) { - CONTEXT winException; + ILib_DumpEnabledContext winException; __try { ILibProcessPipe_Manager_WindowsRunLoopEx(arg); } - __except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winException)) + __except (ILib_WindowsExceptionFilterEx(GetExceptionCode(), GetExceptionInformation(), &winException)) { - ILib_WindowsExceptionDebug(&winException); + ILib_WindowsExceptionDebugEx(&winException); } } void ILibProcessPipe_Manager_Start(void* chain, void* user)