feat: optional CTD reports to gauge stability

This commit is contained in:
goat 2022-07-24 21:23:20 +02:00
parent 1767bbf5b1
commit d2ecddbf35
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
4 changed files with 57 additions and 10 deletions

View file

@ -9,6 +9,10 @@ struct exception_info
DWORD ProcessId; DWORD ProcessId;
BOOL DoFullDump; BOOL DoFullDump;
wchar_t DumpPath[1000]; wchar_t DumpPath[1000];
// For metrics
DWORD ExceptionCode;
long long Lifetime;
}; };
constexpr wchar_t SHARED_INFO_FILE_NAME[] = L"DalamudCrashInfoShare"; constexpr wchar_t SHARED_INFO_FILE_NAME[] = L"DalamudCrashInfoShare";

View file

@ -29,6 +29,8 @@ bool g_veh_do_full_dump = false;
exception_info* g_crashhandler_shared_info; exception_info* g_crashhandler_shared_info;
HANDLE g_crashhandler_event; HANDLE g_crashhandler_event;
std::chrono::time_point<std::chrono::system_clock> g_time_start;
bool is_whitelist_exception(const DWORD code) bool is_whitelist_exception(const DWORD code)
{ {
switch (code) switch (code)
@ -293,11 +295,6 @@ LONG exception_handler(EXCEPTION_POINTERS* ex)
auto window_log_str = log.str(); auto window_log_str = log.str();
print_exception_info_extended(ex, log); 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) if (g_crashhandler_shared_info && g_crashhandler_event)
{ {
memset(g_crashhandler_shared_info, 0, sizeof(exception_info)); memset(g_crashhandler_shared_info, 0, sizeof(exception_info));
@ -307,6 +304,15 @@ LONG exception_handler(EXCEPTION_POINTERS* ex)
g_crashhandler_shared_info->ProcessId = GetCurrentProcessId(); g_crashhandler_shared_info->ProcessId = GetCurrentProcessId();
g_crashhandler_shared_info->ExceptionPointers = ex; g_crashhandler_shared_info->ExceptionPointers = ex;
g_crashhandler_shared_info->DoFullDump = g_veh_do_full_dump; 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<std::chrono::seconds>(
time_now.time_since_epoch()).count()
- std::chrono::duration_cast<std::chrono::seconds>(
g_time_start.time_since_epoch()).count();
g_crashhandler_shared_info->Lifetime = lifetime;
SetEvent(g_crashhandler_event); SetEvent(g_crashhandler_event);
} }
@ -402,6 +408,7 @@ bool veh::add_handler(bool doFullDump, std::string workingDirectory)
SetUnhandledExceptionFilter(nullptr); SetUnhandledExceptionFilter(nullptr);
g_veh_do_full_dump = doFullDump; 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); auto file_mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(exception_info), SHARED_INFO_FILE_NAME);
if (!file_mapping) { if (!file_mapping) {

View file

@ -1,11 +1,13 @@
#include <iostream> #include <iostream>
#include <sstream>
#include <windows.h> #include <windows.h>
#include <minidumpapiset.h> #include <minidumpapiset.h>
#include <tlhelp32.h> #include <tlhelp32.h>
#include <winhttp.h>
#include "../Dalamud.Boot/crashhandler_shared.h" #include "../Dalamud.Boot/crashhandler_shared.h"
DWORD WINAPI MyThreadFunction(LPVOID lpParam) DWORD WINAPI ExitCheckThread(LPVOID lpParam)
{ {
while (true) while (true)
{ {
@ -53,7 +55,7 @@ int main()
CreateThread( CreateThread(
NULL, // default security attributes NULL, // default security attributes
0, // use default stack size 0, // use default stack size
MyThreadFunction, // thread function name ExitCheckThread, // thread function name
NULL, // argument to thread function NULL, // argument to thread function
0, // use default creation flags 0, // use default creation flags
NULL); // returns the thread identifier NULL); // returns the thread identifier
@ -132,5 +134,38 @@ int main()
CloseHandle(process); CloseHandle(process);
CloseHandle(file_mapping); 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; return 0;
} }

View file

@ -48,13 +48,13 @@
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Dbghelp.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Winhttp.lib;Dbghelp.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol> <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -64,7 +64,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
</ClCompile> </ClCompile>
<Link> <Link>
@ -72,6 +72,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Dbghelp.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>