windows dumps

This commit is contained in:
2026-01-11 18:17:44 -05:00
parent 3117f190a5
commit 283d3fd852

View File

@@ -47,8 +47,6 @@ namespace anm2ed
namespace namespace
{ {
#ifdef _WIN32 #ifdef _WIN32
namespace
{
std::filesystem::path g_minidump_dir{}; std::filesystem::path g_minidump_dir{};
PVOID g_vectored_handler{}; PVOID g_vectored_handler{};
LONG g_dump_in_progress{}; LONG g_dump_in_progress{};
@@ -62,16 +60,17 @@ namespace anm2ed
GetLocalTime(&st); GetLocalTime(&st);
auto pid = GetCurrentProcessId(); auto pid = GetCurrentProcessId();
auto code = exceptionPointers && exceptionPointers->ExceptionRecord ? exceptionPointers->ExceptionRecord->ExceptionCode : 0u; auto code = exceptionPointers && exceptionPointers->ExceptionRecord
? exceptionPointers->ExceptionRecord->ExceptionCode
: 0u;
auto filename = auto filename = std::format("anm2ed_{:04}{:02}{:02}_{:02}{:02}{:02}_pid{:08x}_code{:08x}.dmp", st.wYear,
std::format("anm2ed_{:04}{:02}{:02}_{:02}{:02}{:02}_pid{:08x}_code{:08x}.dmp", st.wYear, st.wMonth, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, pid, code);
st.wDay, st.wHour, st.wMinute, st.wSecond, pid, code);
auto dumpPath = g_minidump_dir / path::from_utf8(filename); auto dumpPath = g_minidump_dir / path::from_utf8(filename);
auto dumpPathW = dumpPath.wstring(); auto dumpPathW = dumpPath.wstring();
HANDLE file = HANDLE file = CreateFileW(dumpPathW.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
CreateFileW(dumpPathW.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); FILE_ATTRIBUTE_NORMAL, nullptr);
if (file == INVALID_HANDLE_VALUE) return; if (file == INVALID_HANDLE_VALUE) return;
MINIDUMP_EXCEPTION_INFORMATION mei{}; MINIDUMP_EXCEPTION_INFORMATION mei{};
@@ -79,7 +78,6 @@ namespace anm2ed
mei.ExceptionPointers = exceptionPointers; mei.ExceptionPointers = exceptionPointers;
mei.ClientPointers = FALSE; mei.ClientPointers = FALSE;
// Full memory is large but most useful for user-submitted dumps.
const MINIDUMP_TYPE dumpType = MiniDumpWithFullMemory; const MINIDUMP_TYPE dumpType = MiniDumpWithFullMemory;
MiniDumpWriteDump(GetCurrentProcess(), pid, file, dumpType, exceptionPointers ? &mei : nullptr, nullptr, nullptr); MiniDumpWriteDump(GetCurrentProcess(), pid, file, dumpType, exceptionPointers ? &mei : nullptr, nullptr, nullptr);
@@ -98,7 +96,6 @@ namespace anm2ed
windows_minidump_write(exceptionPointers); windows_minidump_write(exceptionPointers);
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
} // namespace
void windows_minidumps_configure() void windows_minidumps_configure()
{ {
@@ -112,85 +109,11 @@ namespace anm2ed
g_minidump_dir = dumpDir; g_minidump_dir = dumpDir;
// Install both: vectored handler (more reliable) and unhandled filter (fallback).
if (!g_vectored_handler) g_vectored_handler = AddVectoredExceptionHandler(1, windows_vectored_exception_handler); if (!g_vectored_handler) g_vectored_handler = AddVectoredExceptionHandler(1, windows_vectored_exception_handler);
SetUnhandledExceptionFilter(windows_unhandled_exception_filter); SetUnhandledExceptionFilter(windows_unhandled_exception_filter);
logger.info(std::format("MiniDumpWriteDump enabled: {}", path::to_utf8(dumpDir))); logger.info(std::format("MiniDumpWriteDump enabled: {}", path::to_utf8(dumpDir)));
} }
void windows_wer_localdumps_configure()
{
#ifndef DEBUG
return;
#endif
auto prefDir = sdl::preferences_directory_get();
if (prefDir.empty()) return;
std::error_code ec{};
auto dumpDir = prefDir / "crash";
std::filesystem::create_directories(dumpDir, ec);
if (ec)
{
logger.warning(std::format("Failed to create dump directory {}: {}", path::to_utf8(dumpDir), ec.message()));
return;
}
wchar_t modulePath[MAX_PATH]{};
auto charsWritten = GetModuleFileNameW(nullptr, modulePath, MAX_PATH);
if (charsWritten == 0 || charsWritten >= MAX_PATH)
{
logger.warning(std::format("Failed to get module filename for WER LocalDumps (error {}).", GetLastError()));
return;
}
auto exeName = std::filesystem::path(modulePath).filename().wstring();
if (exeName.empty())
{
logger.warning("Failed to determine executable name for WER LocalDumps.");
return;
}
auto subkey = std::wstring(L"Software\\Microsoft\\Windows Error Reporting\\LocalDumps\\") + exeName;
HKEY key{};
auto status =
RegCreateKeyExW(HKEY_CURRENT_USER, subkey.c_str(), 0, nullptr, 0, KEY_SET_VALUE, nullptr, &key, nullptr);
if (status != ERROR_SUCCESS)
{
logger.warning(std::format("Failed to create/open WER LocalDumps key (status {}).", (int)status));
return;
}
auto closeKey = [&]()
{
if (key) RegCloseKey(key);
key = nullptr;
};
auto dumpDirW = dumpDir.wstring();
const DWORD dumpType = 2; // full dump
const DWORD dumpCount = 10;
status = RegSetValueExW(key, L"DumpFolder", 0, REG_EXPAND_SZ, (const BYTE*)dumpDirW.c_str(),
(DWORD)((dumpDirW.size() + 1) * sizeof(wchar_t)));
if (status != ERROR_SUCCESS)
{
logger.warning(std::format("Failed to set WER DumpFolder (status {}).", (int)status));
closeKey();
return;
}
status = RegSetValueExW(key, L"DumpType", 0, REG_DWORD, (const BYTE*)&dumpType, sizeof(dumpType));
if (status != ERROR_SUCCESS) logger.warning(std::format("Failed to set WER DumpType (status {}).", (int)status));
status = RegSetValueExW(key, L"DumpCount", 0, REG_DWORD, (const BYTE*)&dumpCount, sizeof(dumpCount));
if (status != ERROR_SUCCESS) logger.warning(std::format("Failed to set WER DumpCount (status {}).", (int)status));
closeKey();
logger.info(std::format("Crash dumps enabled: {}", path::to_utf8(dumpDir)));
}
#endif #endif
bool socket_paths_send(Socket& socket, const std::vector<std::string>& paths) bool socket_paths_send(Socket& socket, const std::vector<std::string>& paths)