feat(libc): optionally dump indirect memory in Windows crash reports

This commit is contained in:
ivica00 committed 2026-10-13 19:15:33 +02:00
1 parent 61b8742b6b
commit 139bc7b981
2 files changed
+17

No files matched your search

@@ -282,11 +282,24 @@ LONG WINAPI ReportCrash(EXCEPTION_POINTERS* info) {
Report(" r12 %016llx r13 %016llx r14 %016llx r15 %016llx\n", context->R12, context->R13, context->R14, context->R15);
// The words each register points at, to recognise which structure a bad pointer came from.
{
char indirectBuffer[16]{};
const bool indirectMemory = GetEnvironmentVariableA("APS5_CRASH_INDIRECT_MEMORY", indirectBuffer, sizeof(indirectBuffer)) > 0 && indirectBuffer[0] != '\0';
const std::pair<const char*, std::uint64_t> pointers[] = {{"rax", context->Rax}, {"rbx", context->Rbx}, {"rcx", context->Rcx}, {"rdx", context->Rdx}, {"rsi", context->Rsi}, {"rdi", context->Rdi}, {"r12", context->R12}, {"r13", context->R13}, {"r14", context->R14}, {"r15", context->R15}};
for (const auto& [name, value] : pointers) {
if (value < 0x10000 || (value & 7) != 0 || !IsReadable(value) || !IsReadable(value + 0x38)) continue;
const auto* words = reinterpret_cast<const std::uint64_t*>(value);
Report(" [%s] %016llx %016llx %016llx %016llx %016llx %016llx %016llx %016llx\n", name, words[0], words[1], words[2], words[3], words[4], words[5], words[6], words[7]);
if (!indirectMemory) continue;
for (std::size_t i = 0; i < 8; ++i) {
const auto address = words[i];
if (address < 0x10000 || IsExecutable(address)) continue;
std::uint64_t content[8]{};
SIZE_T copied = 0;
if (!ReadProcessMemory(GetCurrentProcess(), reinterpret_cast<const void*>(address), content, sizeof(content), &copied) || copied != sizeof(content)) continue;
Report(" [[%s+0x%llx]] @%016llx %016llx %016llx %016llx %016llx %016llx %016llx %016llx %016llx\n",
name, static_cast<unsigned long long>(i * sizeof(*words)), static_cast<unsigned long long>(address),
content[0], content[1], content[2], content[3], content[4], content[5], content[6], content[7]);
}
}
}
Report(" frame pointer chain:\n");
+4
View File
@@ -171,6 +171,10 @@ most called traced imports (1 calls in total):
Limits are listed in the [libc](../dev/debt/libc.md) and [relinker](../dev/debt/relinker.md) technical debt.
### Windows crash diagnostics
Set `APS5_CRASH_INDIRECT_MEMORY=1` before launching the executable to include up to 64 bytes from each pointer found in the register memory dump. The report labels each block with its register, pointer offset and target address. Inaccessible, incomplete and executable targets are skipped. This additional dump is disabled when the variable is unset or empty.
## Exit codes
`0`: conversion succeeded or help was displayed. `1`: invalid arguments. `2`: conversion failed; the error is printed to stderr. With `--autorun`, successful conversion returns the launched application's exit code.