Skip to content

Report the faulting module, offset and a call stack for native crashes - #138

Merged
Views2k merged 5 commits into
mainfrom
feat/native-crash-capture
Oct 17, 2026
Merged

Views2k merged 5 commits into
mainfrom
feat/native-crash-capture

Conversation

@Views2k

@Views2k Views2k commented Oct 17, 2026

Copy link
Copy Markdown
Owner

What

Crash reports stop guessing about where a native fault happened.

  • Event Log details in full. WindowsFaultEventReader keeps any faulting module file name (lower case, letters, digits, ., _, -, with a .dll/.exe/.sys/.drv extension, or unknown) instead of an allow-list that dropped hooks other software injects (RTSS, overlays), and keeps the module's version. Paths are still rejected.
  • In-process capture. Wisp.NativeRenderer.dll installs a vectored exception handler at startup (WispCrashCaptureInstall). On an access violation (outside the null page, which the runtime uses for its own null checks), in-page error, illegal or privileged instruction, misalignment, stack-buffer overrun or heap corruption, it writes one bounded record, without allocating or handling the exception, to CrashReports/native-<run id>.txt: exception code, thread, faulting address as module+offset, the access kind and address, and a call stack of up to 48 frames as module+offset. At most three records per process.
  • Recovery and export. PreviousRunRecovery attaches the previous run's record to the crash report (RecoveredExitInfo.Native), the report text lists it, and the incident sent to Wisp Tools carries crash.offset, crash.moduleVersion, crash.faultModule, crash.faultOffset and crash.frames. The incident signature is unchanged, so grouping is stable. Tools accepts and shows these fields (wisp-site PR "Accept and show the faulting module, offsets and a native call stack on crash evidence").
  • Release notes, changelog and the in-app catalog gain the Diagnostics bullet.

Why

Two 2.6.12 access violations could only be attributed to wisp.exe: the Event Log offset was never exported and the real faulting module was filtered by the allow-list. With this, the next fault names the module, its version, the offset and the stack.

Checks

  • Native: builds under /W4 /WX; the contract tests (Build-NativeRenderer.ps1 -RunContractTests) include CheckCrashCapture (record format, module naming, access details, stack, buffer bound, idempotent install) and pass on the owner's PC with a GPU.
  • Managed: NativeCrashCaptureTests (parsing the last complete record, sanitising, frame bounds, read-once file handling) and updated WindowsFaultEventReaderTests (any file name kept, paths dropped, module version kept when well formed). CI runs the suite.
  • Not reproduced live: the handler only writes when a real fault occurs.

Crash reports kept only an allow-listed faulting module name and no
offset, so two 2.6.12 access violations could only be attributed to
wisp.exe. The Event Log module name is now kept whatever it is (a bare
file name; paths are dropped) together with the module version and the
fault offset, and the native renderer installs a vectored exception
handler that writes the faulting address and a module+offset call
stack to the crash store; the next run attaches it to the report and
sends it to Wisp Tools.
@Views2k
Views2k merged commit 3b7a7be into main Oct 17, 2026
10 checks passed
@Views2k
Views2k deleted the feat/native-crash-capture branch October 17, 2026 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant