fix: lock crash report ring buffer (SMP race) and guard crashpad crash loop
This commit is contained in:
@@ -12,4 +12,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MONTAUK_BUILD_NUMBER 128
|
||||
#define MONTAUK_BUILD_NUMBER 129
|
||||
|
||||
@@ -13,38 +13,40 @@ namespace montauk::abi {
|
||||
|
||||
static int64_t Sys_CrashReport(CrashReportInfo* out) {
|
||||
if (!out) return 0;
|
||||
if (CrashReport::g_reportCount == 0) return 0;
|
||||
|
||||
int oldestIdx = (CrashReport::g_reportHead - CrashReport::g_reportCount + CrashReport::MaxReports) % CrashReport::MaxReports;
|
||||
auto* rep = &CrashReport::g_reports[oldestIdx];
|
||||
// Pop the oldest report into a kernel-local copy under the ring lock,
|
||||
// then marshal into user memory with the lock released.
|
||||
CrashReport::Report rep;
|
||||
int had = CrashReport::TakeOldest(rep);
|
||||
if (had == 0) return 0;
|
||||
|
||||
out->pid = rep->pid;
|
||||
out->pid = rep.pid;
|
||||
int pn;
|
||||
for (pn = 0; pn < 63 && rep->processName[pn]; pn++) out->processName[pn] = rep->processName[pn];
|
||||
for (pn = 0; pn < 63 && rep.processName[pn]; pn++) out->processName[pn] = rep.processName[pn];
|
||||
out->processName[pn] = '\0';
|
||||
out->exceptionVector = rep->exceptionVector;
|
||||
out->exceptionVector = rep.exceptionVector;
|
||||
int en;
|
||||
for (en = 0; en < 31 && rep->exceptionName[en]; en++) out->exceptionName[en] = rep->exceptionName[en];
|
||||
for (en = 0; en < 31 && rep.exceptionName[en]; en++) out->exceptionName[en] = rep.exceptionName[en];
|
||||
out->exceptionName[en] = '\0';
|
||||
out->faultingAddress = rep->faultingAddress;
|
||||
out->instructionPointer = rep->instructionPointer;
|
||||
out->stackPointer = rep->stackPointer;
|
||||
out->codeSegment = rep->codeSegment;
|
||||
out->flags = rep->flags;
|
||||
out->stackSegment = rep->stackSegment;
|
||||
out->pfPresent = rep->pfPresent;
|
||||
out->pfWrite = rep->pfWrite;
|
||||
out->pfUser = rep->pfUser;
|
||||
out->pfReservedWrite = rep->pfReservedWrite;
|
||||
out->pfInstructionFetch = rep->pfInstructionFetch;
|
||||
out->pfProtectionKey = rep->pfProtectionKey;
|
||||
out->pfShadowStack = rep->pfShadowStack;
|
||||
out->pfSGX = rep->pfSGX;
|
||||
out->timestampTick = rep->timestampTick;
|
||||
rep->valid = false;
|
||||
CrashReport::g_reportCount--;
|
||||
out->faultingAddress = rep.faultingAddress;
|
||||
out->instructionPointer = rep.instructionPointer;
|
||||
out->stackPointer = rep.stackPointer;
|
||||
out->codeSegment = rep.codeSegment;
|
||||
out->flags = rep.flags;
|
||||
out->stackSegment = rep.stackSegment;
|
||||
out->pfPresent = rep.pfPresent;
|
||||
out->pfWrite = rep.pfWrite;
|
||||
out->pfUser = rep.pfUser;
|
||||
out->pfReservedWrite = rep.pfReservedWrite;
|
||||
out->pfInstructionFetch = rep.pfInstructionFetch;
|
||||
out->pfProtectionKey = rep.pfProtectionKey;
|
||||
out->pfShadowStack = rep.pfShadowStack;
|
||||
out->pfSGX = rep.pfSGX;
|
||||
out->timestampTick = rep.timestampTick;
|
||||
|
||||
return CrashReport::g_reportCount + 1;
|
||||
// Preserve the original contract: count of reports present before this
|
||||
// call (i.e. including the one just returned).
|
||||
return had;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user