From 805a887f2e3eb277e31b5ce363e5727d6086eda7 Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 24 Jul 2022 18:49:46 +0200 Subject: [PATCH] feat: add minidump writer --- Dalamud.Boot/Dalamud.Boot.vcxproj | 3 +- Dalamud.Boot/Dalamud.Boot.vcxproj.filters | 3 +- Dalamud.Boot/crashhandler_shared.h | 15 ++ Dalamud.Boot/dllmain.cpp | 2 +- Dalamud.Boot/veh.cpp | 78 ++++++++-- Dalamud.Boot/veh.h | 2 +- Dalamud.sln | 14 ++ DalamudCrashHandler/DalamudCrashHandler.cpp | 136 ++++++++++++++++++ DalamudCrashHandler/DalamudCrashHandler.rc | 71 +++++++++ .../DalamudCrashHandler.vcxproj | 93 ++++++++++++ .../DalamudCrashHandler.vcxproj.filters | 40 ++++++ DalamudCrashHandler/dalamud.ico | Bin 0 -> 53179 bytes DalamudCrashHandler/resource.h | 16 +++ build/DalamudBuild.cs | 16 +++ 14 files changed, 477 insertions(+), 12 deletions(-) create mode 100644 Dalamud.Boot/crashhandler_shared.h create mode 100644 DalamudCrashHandler/DalamudCrashHandler.cpp create mode 100644 DalamudCrashHandler/DalamudCrashHandler.rc create mode 100644 DalamudCrashHandler/DalamudCrashHandler.vcxproj create mode 100644 DalamudCrashHandler/DalamudCrashHandler.vcxproj.filters create mode 100644 DalamudCrashHandler/dalamud.ico create mode 100644 DalamudCrashHandler/resource.h diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj b/Dalamud.Boot/Dalamud.Boot.vcxproj index 3733fe388..77783e269 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj @@ -162,6 +162,7 @@ + @@ -182,4 +183,4 @@ - + \ No newline at end of file diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters index 27483eeed..8b4483684 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters @@ -139,6 +139,7 @@ MinHook + @@ -146,4 +147,4 @@ - + \ No newline at end of file diff --git a/Dalamud.Boot/crashhandler_shared.h b/Dalamud.Boot/crashhandler_shared.h new file mode 100644 index 000000000..0c1649cc4 --- /dev/null +++ b/Dalamud.Boot/crashhandler_shared.h @@ -0,0 +1,15 @@ +#pragma once + +#include "windows.h" + +struct exception_info +{ + void* ExceptionPointers; // Cannot dereference! + DWORD ThreadId; + DWORD ProcessId; + BOOL DoFullDump; + wchar_t DumpPath[1000]; +}; + +constexpr wchar_t SHARED_INFO_FILE_NAME[] = L"DalamudCrashInfoShare"; +constexpr wchar_t CRASHDUMP_EVENT_NAME[] = L"Global\\DalamudRequestWriteDump"; diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp index 5a2665f09..d5660e976 100644 --- a/Dalamud.Boot/dllmain.cpp +++ b/Dalamud.Boot/dllmain.cpp @@ -136,7 +136,7 @@ DWORD WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { if (utils::is_running_on_linux()) { logging::I("=> VEH was disabled, running on linux"); } else if (g_startInfo.BootVehEnabled) { - if (veh::add_handler(g_startInfo.BootVehFull)) + if (veh::add_handler(g_startInfo.BootVehFull, g_startInfo.WorkingDirectory)) logging::I("=> Done!"); else logging::I("=> Failed!"); diff --git a/Dalamud.Boot/veh.cpp b/Dalamud.Boot/veh.cpp index 1ab0e5c9b..b29c38b07 100644 --- a/Dalamud.Boot/veh.cpp +++ b/Dalamud.Boot/veh.cpp @@ -9,6 +9,8 @@ #include "logging.h" #include "utils.h" +#include "crashhandler_shared.h" + #pragma comment(lib, "comctl32.lib") #if defined _M_IX86 @@ -24,6 +26,9 @@ PVOID g_veh_handle = nullptr; bool g_veh_do_full_dump = false; +exception_info* g_crashhandler_shared_info; +HANDLE g_crashhandler_event; + bool is_whitelist_exception(const DWORD code) { switch (code) @@ -292,14 +297,19 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) ex_info.ClientPointers = false; ex_info.ExceptionPointers = ex; ex_info.ThreadId = GetCurrentThreadId(); - - auto miniDumpType = MiniDumpWithDataSegs; - if (g_veh_do_full_dump) - miniDumpType = MiniDumpWithFullMemory; - HANDLE file = CreateFileW(dmp_path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - //MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, miniDumpType, &ex_info, nullptr, nullptr); - CloseHandle(file); + if (g_crashhandler_shared_info && g_crashhandler_event) + { + memset(g_crashhandler_shared_info, 0, sizeof(exception_info)); + + wcsncpy_s(g_crashhandler_shared_info->DumpPath, dmp_path.c_str(), 1000); + g_crashhandler_shared_info->ThreadId = GetThreadId(GetCurrentThread()); + g_crashhandler_shared_info->ProcessId = GetCurrentProcessId(); + g_crashhandler_shared_info->ExceptionPointers = ex; + g_crashhandler_shared_info->DoFullDump = g_veh_do_full_dump; + + SetEvent(g_crashhandler_event); + } std::wstring message; void* fn; @@ -384,7 +394,7 @@ LONG exception_handler(EXCEPTION_POINTERS* ex) return EXCEPTION_CONTINUE_SEARCH; } -bool veh::add_handler(bool doFullDump) +bool veh::add_handler(bool doFullDump, std::string workingDirectory) { if (g_veh_handle) return false; @@ -393,6 +403,58 @@ bool veh::add_handler(bool doFullDump) g_veh_do_full_dump = doFullDump; + auto file_mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(exception_info), SHARED_INFO_FILE_NAME); + if (!file_mapping) { + std::cout << "Could not map info share file.\n"; + g_crashhandler_shared_info = nullptr; + } + else + { + g_crashhandler_shared_info = (exception_info*)MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(exception_info)); + if (!g_crashhandler_shared_info) { + std::cout << "Could not map view of info share file.\n"; + } + } + + g_crashhandler_event = CreateEvent( + NULL, // default security attributes + TRUE, // manual-reset event + FALSE, // initial state is nonsignaled + CRASHDUMP_EVENT_NAME // object name + ); + + if (!g_crashhandler_event) + { + std::cout << "Couldn't acquire event handle\n"; + } + + auto handler_path = std::filesystem::path(workingDirectory) / "DalamudCrashHandler.exe"; + + // additional information + STARTUPINFO si; + PROCESS_INFORMATION pi; + + // set the size of the structures + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + + CreateProcess( handler_path.c_str(), // the path + NULL, // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + 0, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses) + ); + + // Close process and thread handles. + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + return g_veh_handle != nullptr; } diff --git a/Dalamud.Boot/veh.h b/Dalamud.Boot/veh.h index bf0c549f3..7820d6982 100644 --- a/Dalamud.Boot/veh.h +++ b/Dalamud.Boot/veh.h @@ -2,6 +2,6 @@ namespace veh { - bool add_handler(bool doFullDump); + bool add_handler(bool doFullDump, std::string workingDirectory); bool remove_handler(); } diff --git a/Dalamud.sln b/Dalamud.sln index 546e31dfe..a9cdf123d 100644 --- a/Dalamud.sln +++ b/Dalamud.sln @@ -34,6 +34,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FFXIVClientStructs", "lib\F EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FFXIVClientStructs.Generators", "lib\FFXIVClientStructs\FFXIVClientStructs.Generators\FFXIVClientStructs.Generators.csproj", "{05AB2F46-268B-4915-806F-DDF813E2D59D}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DalamudCrashHandler", "DalamudCrashHandler\DalamudCrashHandler.vcxproj", "{317A264C-920B-44A1-8A34-F3A6827B0705}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -186,6 +188,18 @@ Global {05AB2F46-268B-4915-806F-DDF813E2D59D}.Release|x64.Build.0 = Release|Any CPU {05AB2F46-268B-4915-806F-DDF813E2D59D}.Release|x86.ActiveCfg = Release|Any CPU {05AB2F46-268B-4915-806F-DDF813E2D59D}.Release|x86.Build.0 = Release|Any CPU + {317A264C-920B-44A1-8A34-F3A6827B0705}.Debug|Any CPU.ActiveCfg = Debug|x64 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Debug|Any CPU.Build.0 = Debug|x64 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Debug|x64.ActiveCfg = Debug|x64 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Debug|x64.Build.0 = Debug|x64 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Debug|x86.ActiveCfg = Debug|Win32 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Debug|x86.Build.0 = Debug|Win32 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Release|Any CPU.ActiveCfg = Release|x64 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Release|Any CPU.Build.0 = Release|x64 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x64.ActiveCfg = Release|x64 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x64.Build.0 = Release|x64 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x86.ActiveCfg = Release|Win32 + {317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp new file mode 100644 index 000000000..e7bc79055 --- /dev/null +++ b/DalamudCrashHandler/DalamudCrashHandler.cpp @@ -0,0 +1,136 @@ +#include +#include +#include +#include + +#include "../Dalamud.Boot/crashhandler_shared.h" + +DWORD WINAPI MyThreadFunction(LPVOID lpParam) +{ + while (true) + { + PROCESSENTRY32 entry; + entry.dwSize = sizeof(PROCESSENTRY32); + + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); + + if (Process32First(snapshot, &entry) == TRUE) + { + bool had_xiv = false; + + while (Process32Next(snapshot, &entry) == TRUE) + { + // Exit if there's another crash handler + // TODO(goat): We should make this more robust and ensure that there is one per PID + if (_wcsicmp(entry.szExeFile, L"DalamudCrashHandler.exe") == 0 && + entry.th32ProcessID != GetCurrentProcessId()) + { + ExitProcess(0); + break; + } + + if (_wcsicmp(entry.szExeFile, L"ffxiv_dx11.exe") == 0) + { + had_xiv = true; + } + } + + if (!had_xiv) + { + ExitProcess(0); + break; + } + } + + CloseHandle(snapshot); + + Sleep(1000); + } +} + +int main() +{ + CreateThread( + NULL, // default security attributes + 0, // use default stack size + MyThreadFunction, // thread function name + NULL, // argument to thread function + 0, // use default creation flags + NULL); // returns the thread identifier + + auto file_mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(exception_info), SHARED_INFO_FILE_NAME); + if (!file_mapping) { + std::cout << "Could not map info share file.\n"; + return -2; + } + + auto file_ptr = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, sizeof(exception_info)); + if (!file_ptr) { + std::cout << "Could not map view of info share file.\n"; + return -3; + } + + std::cout << "Waiting for crash...\n"; + + auto crash_event = CreateEvent( + NULL, // default security attributes + TRUE, // manual-reset event + FALSE, // initial state is nonsignaled + CRASHDUMP_EVENT_NAME // object name + ); + + if (!crash_event) + { + std::cout << "Couldn't acquire event handle\n"; + return -1; + } + + auto wait_result = WaitForSingleObject(crash_event, INFINITE); + std::cout << "Crash triggered, writing dump!\n"; + + auto info_share = (exception_info*)file_ptr; + + if (!info_share->ExceptionPointers) + { + std::cout << "info_share->ExceptionPointers was nullptr\n"; + return -4; + } + + MINIDUMP_EXCEPTION_INFORMATION mdmp_info; + mdmp_info.ClientPointers = true; + mdmp_info.ExceptionPointers = (PEXCEPTION_POINTERS)info_share->ExceptionPointers; + mdmp_info.ThreadId = info_share->ThreadId; + + + std::cout << "Dump for " << info_share->ProcessId << std::endl; + HANDLE file = CreateFileW(info_share->DumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (!file) + { + auto hr = GetLastError(); + std::cout << "Failed to open dump file: " << std::hex << hr << std::endl; + return -6; + } + + auto process = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, info_share->ProcessId); + if (!process) + { + auto hr = GetLastError(); + std::cout << "Failed to open " << info_share->ProcessId << ": " << std::hex << hr << std::endl; + return -6; + } + + auto success = MiniDumpWriteDump(process, info_share->ProcessId, file, MiniDumpWithFullMemory, &mdmp_info, NULL, NULL); + if (!success) + { + auto hr = GetLastError(); + std::cout << "Failed: " << std::hex << hr << std::endl; + } + + // TODO(goat): Technically, we should have another event or a semaphore to block xiv while dumping... + + CloseHandle(file); + CloseHandle(process); + CloseHandle(file_mapping); + + return 0; +} diff --git a/DalamudCrashHandler/DalamudCrashHandler.rc b/DalamudCrashHandler/DalamudCrashHandler.rc new file mode 100644 index 000000000..daa41a282 --- /dev/null +++ b/DalamudCrashHandler/DalamudCrashHandler.rc @@ -0,0 +1,71 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United Kingdom) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "dalamud.ico" + +#endif // English (United Kingdom) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/DalamudCrashHandler/DalamudCrashHandler.vcxproj b/DalamudCrashHandler/DalamudCrashHandler.vcxproj new file mode 100644 index 000000000..b56628f6a --- /dev/null +++ b/DalamudCrashHandler/DalamudCrashHandler.vcxproj @@ -0,0 +1,93 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {317a264c-920b-44a1-8a34-f3a6827b0705} + DalamudCrashHandler + 10.0 + ..\bin\$(Configuration)\ + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Windows + true + Dbghelp.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + mainCRTStartup + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DalamudCrashHandler/DalamudCrashHandler.vcxproj.filters b/DalamudCrashHandler/DalamudCrashHandler.vcxproj.filters new file mode 100644 index 000000000..890f66520 --- /dev/null +++ b/DalamudCrashHandler/DalamudCrashHandler.vcxproj.filters @@ -0,0 +1,40 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/DalamudCrashHandler/dalamud.ico b/DalamudCrashHandler/dalamud.ico new file mode 100644 index 0000000000000000000000000000000000000000..1cd63765d401c387188f8588076582da1369f71a GIT binary patch literal 53179 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 V`M7xULJmNEEY0jptBm2X{{ysvb7}wp literal 0 HcmV?d00001 diff --git a/DalamudCrashHandler/resource.h b/DalamudCrashHandler/resource.h new file mode 100644 index 000000000..cdeb6ea3c --- /dev/null +++ b/DalamudCrashHandler/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by DalamudCrashHandler.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/build/DalamudBuild.cs b/build/DalamudBuild.cs index 01d6d3038..318af7851 100644 --- a/build/DalamudBuild.cs +++ b/build/DalamudBuild.cs @@ -31,6 +31,9 @@ public class DalamudBuild : NukeBuild AbsolutePath DalamudBootProjectDir => RootDirectory / "Dalamud.Boot"; AbsolutePath DalamudBootProjectFile => DalamudBootProjectDir / "Dalamud.Boot.vcxproj"; + + AbsolutePath DalamudCrashHandlerProjectDir => RootDirectory / "DalamudCrashHandler"; + AbsolutePath DalamudCrashHandlerProjectFile => DalamudBootProjectDir / "DalamudCrashHandler.vcxproj"; AbsolutePath InjectorProjectDir => RootDirectory / "Dalamud.Injector"; AbsolutePath InjectorProjectFile => InjectorProjectDir / "Dalamud.Injector.csproj"; @@ -71,6 +74,14 @@ public class DalamudBuild : NukeBuild .SetTargetPath(DalamudBootProjectFile) .SetConfiguration(Configuration)); }); + + Target CompileDalamudCrashHandler => _ => _ + .Executes(() => + { + MSBuildTasks.MSBuild(s => s + .SetTargetPath(DalamudCrashHandlerProjectFile) + .SetConfiguration(Configuration)); + }); Target CompileInjector => _ => _ .DependsOn(Restore) @@ -117,6 +128,11 @@ public class DalamudBuild : NukeBuild .SetProjectFile(DalamudBootProjectFile) .SetConfiguration(Configuration) .SetTargets("Clean")); + + MSBuildTasks.MSBuild(s => s + .SetProjectFile(DalamudCrashHandlerProjectFile) + .SetConfiguration(Configuration) + .SetTargets("Clean")); DotNetTasks.DotNetClean(s => s .SetProject(InjectorProjectFile)