From d2ecddbf3553eb4f91085c65e0428d9dccd47f60 Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 24 Jul 2022 21:23:20 +0200 Subject: [PATCH] feat: optional CTD reports to gauge stability --- Dalamud.Boot/crashhandler_shared.h | 4 ++ Dalamud.Boot/veh.cpp | 17 +++++--- DalamudCrashHandler/DalamudCrashHandler.cpp | 39 ++++++++++++++++++- .../DalamudCrashHandler.vcxproj | 7 ++-- 4 files changed, 57 insertions(+), 10 deletions(-) diff --git a/Dalamud.Boot/crashhandler_shared.h b/Dalamud.Boot/crashhandler_shared.h index 0c1649cc4..6b17bb11f 100644 --- a/Dalamud.Boot/crashhandler_shared.h +++ b/Dalamud.Boot/crashhandler_shared.h @@ -9,6 +9,10 @@ struct exception_info DWORD ProcessId; BOOL DoFullDump; wchar_t DumpPath[1000]; + + // For metrics + DWORD ExceptionCode; + long long Lifetime; }; constexpr wchar_t SHARED_INFO_FILE_NAME[] = L"DalamudCrashInfoShare"; diff --git a/Dalamud.Boot/veh.cpp b/Dalamud.Boot/veh.cpp index b29c38b07..890c7ab0d 100644 --- a/Dalamud.Boot/veh.cpp +++ b/Dalamud.Boot/veh.cpp @@ -29,6 +29,8 @@ bool g_veh_do_full_dump = false; exception_info* g_crashhandler_shared_info; HANDLE g_crashhandler_event; +std::chrono::time_point g_time_start; + bool is_whitelist_exception(const DWORD code) { switch (code) @@ -292,11 +294,6 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) print_exception_info(ex, log); auto window_log_str = log.str(); print_exception_info_extended(ex, log); - - MINIDUMP_EXCEPTION_INFORMATION ex_info; - ex_info.ClientPointers = false; - ex_info.ExceptionPointers = ex; - ex_info.ThreadId = GetCurrentThreadId(); if (g_crashhandler_shared_info && g_crashhandler_event) { @@ -307,6 +304,15 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) g_crashhandler_shared_info->ProcessId = GetCurrentProcessId(); g_crashhandler_shared_info->ExceptionPointers = ex; g_crashhandler_shared_info->DoFullDump = g_veh_do_full_dump; + g_crashhandler_shared_info->ExceptionCode = ex->ExceptionRecord->ExceptionCode; + + const auto time_now = std::chrono::system_clock::now(); + auto lifetime = std::chrono::duration_cast( + time_now.time_since_epoch()).count() + - std::chrono::duration_cast( + g_time_start.time_since_epoch()).count(); + + g_crashhandler_shared_info->Lifetime = lifetime; SetEvent(g_crashhandler_event); } @@ -402,6 +408,7 @@ bool veh::add_handler(bool doFullDump, std::string workingDirectory) SetUnhandledExceptionFilter(nullptr); g_veh_do_full_dump = doFullDump; + g_time_start = std::chrono::system_clock::now(); auto file_mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(exception_info), SHARED_INFO_FILE_NAME); if (!file_mapping) { diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp index e7bc79055..2fc85e495 100644 --- a/DalamudCrashHandler/DalamudCrashHandler.cpp +++ b/DalamudCrashHandler/DalamudCrashHandler.cpp @@ -1,11 +1,13 @@ #include +#include #include #include #include +#include #include "../Dalamud.Boot/crashhandler_shared.h" -DWORD WINAPI MyThreadFunction(LPVOID lpParam) +DWORD WINAPI ExitCheckThread(LPVOID lpParam) { while (true) { @@ -53,7 +55,7 @@ int main() CreateThread( NULL, // default security attributes 0, // use default stack size - MyThreadFunction, // thread function name + ExitCheckThread, // thread function name NULL, // argument to thread function 0, // use default creation flags NULL); // returns the thread identifier @@ -132,5 +134,38 @@ int main() CloseHandle(process); CloseHandle(file_mapping); + if (getenv("DALAMUD_NO_METRIC")) + return 0; + + HINTERNET internet = WinHttpOpen(L"DALAMUDCRASHHANDLER", WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, NULL, NULL, WINHTTP_FLAG_SECURE_DEFAULTS); + HINTERNET connect = NULL, request = NULL; + if (internet) + { + connect = WinHttpConnect(internet, L"kamori.goats.dev", INTERNET_DEFAULT_HTTPS_PORT, 0); + } + + if (connect) + { + std::wstringstream url{ L"/Dalamud/Metric/ReportCrash/" }; + url << "?lt=" << info_share->Lifetime << "&code=" << std::hex << info_share->ExceptionCode; + + request = WinHttpOpenRequest(internet, L"GET", url.str().c_str(), NULL, NULL, NULL, 0); + } + + if (request) + { + bool sent = WinHttpSendRequest(request, + WINHTTP_NO_ADDITIONAL_HEADERS, + 0, WINHTTP_NO_REQUEST_DATA, 0, + 0, 0); + + if (!sent) + std::cout << "Failed to send metric: " << std::hex << GetLastError() << std::endl; + } + + if (request) WinHttpCloseHandle(request); + if (connect) WinHttpCloseHandle(connect); + if (internet) WinHttpCloseHandle(internet); + return 0; } diff --git a/DalamudCrashHandler/DalamudCrashHandler.vcxproj b/DalamudCrashHandler/DalamudCrashHandler.vcxproj index b56628f6a..e4aaa3eb1 100644 --- a/DalamudCrashHandler/DalamudCrashHandler.vcxproj +++ b/DalamudCrashHandler/DalamudCrashHandler.vcxproj @@ -48,13 +48,13 @@ Level3 true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Windows true - Dbghelp.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + Winhttp.lib;Dbghelp.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) mainCRTStartup @@ -64,7 +64,7 @@ true true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true @@ -72,6 +72,7 @@ true true true + Dbghelp.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)