mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-25 17:54:42 +01:00
Crash reports: the game's own fatal crashes come with the memory their stacks point at
Most crashes are caught by the game's own fatal handlers, which write a dump of thread stacks only; the launcher could only copy it after the game had exited. A crash on a freed or overwritten object then showed the faulting registers but not the object or the list it came from. - game_fatal_dump: the game's MiniDumpWriteDump import points at ReSkate. Before the game writes its dump, the crash reporter takes its own of the still-running game for the faulting thread; the game's dump follows as before. Reports say capture.source "game-fatal-handler". - The reporter's dumps include the memory the stacks point at (MiniDumpWithIndirectlyReferencedMemory), a few MB more a report. - The shared report says who asked for the dump (protocol version 4). - Tests: a game-handler crash is captured with a heap block only its stack points at; ReSkate's own capture keeps it too.
This commit is contained in:
1 parent
ea3f081367
commit
3249f747dc
10 files changed
+169
-18
No files matched your search
@@ -104,16 +104,25 @@ StartResult start(const std::filesystem::path& log_directory) noexcept {
|
||||
return StartResult::ready;
|
||||
} catch (...) { return StartResult::failed; }
|
||||
}
|
||||
void capture(EXCEPTION_POINTERS* exception) noexcept {
|
||||
if (!exception || InterlockedCompareExchange(&capturing, 1, 0) != 0) return;
|
||||
report->thread_id = GetCurrentThreadId();
|
||||
namespace {
|
||||
void capture_on(DWORD thread_id, EXCEPTION_POINTERS* exception, CaptureSource source) noexcept {
|
||||
if (!exception || !thread_id || InterlockedCompareExchange(&capturing, 1, 0) != 0) return;
|
||||
report->thread_id = thread_id;
|
||||
report->exception = exception;
|
||||
report->source = source;
|
||||
MemoryBarrier();
|
||||
if (SetEvent(handles[requested])) {
|
||||
const HANDLE wait_for[]{handles[captured], helper};
|
||||
WaitForMultipleObjects(2, wait_for, FALSE, capture_timeout_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
void capture(EXCEPTION_POINTERS* exception) noexcept {
|
||||
capture_on(GetCurrentThreadId(), exception, CaptureSource::unhandled_exception);
|
||||
}
|
||||
void capture_game_fatal(DWORD thread_id, EXCEPTION_POINTERS* exception) noexcept {
|
||||
capture_on(thread_id, exception, CaptureSource::game_fatal_handler);
|
||||
}
|
||||
void set_destination(std::wstring_view destination) noexcept {
|
||||
if (auto* const shared = report) copy_cut(shared->destination, destination);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user