-
-
Notifications
You must be signed in to change notification settings - Fork 3
Round-2 stability: profiler honesty, GI backend logging, crash-triage kit, test repairs #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # Windows crash triage — native AVs in Perry-compiled games | ||
|
|
||
| Written after the 2026-07-04 round-2 audit, where the Bloom Shooter hit the | ||
| same access violation in three scripted runs (`main.exe+0xe8e5`, read of an | ||
| address 8 bytes below a page boundary, exception c0000005) and the fault | ||
| could not be reproduced after a relink. Everything below is the kit that | ||
| makes the *next* occurrence a five-minute diagnosis instead of a hunt. | ||
|
|
||
| ## What we know about the 2026-07 AV (EN-020) | ||
|
|
||
| - Same faulting instruction offset in all three crashes; faulting address | ||
| `0x…FFF8` = a read that walked off the end of a heap allocation onto an | ||
| unmapped page. Classic buffer-overrun-read signature: the overrun likely | ||
| happens often and only faults when the allocator places the buffer at | ||
| the end of a page — which makes it **layout-sensitive**: any relink | ||
| reshuffles the odds. Our fishing runs on a rebuilt binary (60 s with the | ||
| same workloads, plus a 19-transition feature-toggle gauntlet) did not | ||
| reproduce. | ||
| - Crash contexts (shooter audit tour): 20–56 s into runs that combined the | ||
| profiler (enabled), profiler-string FFI reads (`getProfilerOverlay` / | ||
| `getProfilerFrameHistory`), stage transitions, and in two cases runtime | ||
| feature disables. Toggles alone were exonerated by the gauntlet run; | ||
| string churn alone was exonerated by run 3 (crashed with only ~8 tiny | ||
| prints). No Rust panic output on stderr — this is raw UB, not a panic | ||
| (the engine builds with `panic = "abort"`, which would print first). | ||
| - Suspect space: Perry runtime heap/string handling at the FFI boundary, | ||
| or an engine-side out-of-bounds read into a heap buffer. The faulting | ||
| module offset (0xe8e5, very low in `.text`) is consistent with a small | ||
| shared helper (memcpy-class) rather than a leaf feature. | ||
|
|
||
| ## Standing infrastructure on the dev box | ||
|
|
||
| - **WER LocalDumps** (HKCU, no admin needed): full dumps for `main.exe` | ||
| land in `shooter/tools/.testout/dumps/`, dialog suppressed | ||
| (`Windows Error Reporting\DontShowUI = 1`). Configured 2026-07-04; | ||
| survives reboots. Every crash from now on leaves a `.dmp`. | ||
| - **Symbols**: `native/windows/Cargo.toml` sets | ||
| `[profile.release] debug = "line-tables-only"`, so the staticlib carries | ||
| line tables at negligible cost. Link the game with | ||
| `perry compile src/main.ts -o main --debug-symbols` to get `main.pdb` | ||
| next to the exe (lld `/DEBUG`). Keep the exe+pdb pair that produced any | ||
| dump. | ||
| - **Symbolisation** (LLVM is installed at `C:\Program Files\LLVM`): | ||
| `llvm-symbolizer --obj=main.exe --use-native-pdb-reader 0x<RVA>` maps | ||
| the WER event's module offset to a function/line. For a full stack, | ||
| open the `.dmp` in WinDbg (`winget install Microsoft.WinDbg`) with | ||
| `.sympath` pointing at the exe's folder, then `!analyze -v`. | ||
| - The WER Application-log event (Id 1000) alone already gives the module | ||
| + offset — check it first: | ||
| `Get-WinEvent -FilterHashtable @{LogName='Application'; Id=1000} -MaxEvents 3`. | ||
|
|
||
| ## Repro harness | ||
|
|
||
| The shooter's audit tour (`AUDIT` block for `src/main.ts`, preserved with | ||
| the round-2 artifacts) drives the game unattended: scripted combat at the | ||
| enemy-pool max, camera pose hops, profiler-string churn every 2 s, and an | ||
| optional feature-toggle gauntlet. Historical crash probability was 3/3 | ||
| within 60 s on the af98dbe-era binary; treat every future tour run as a | ||
| fishing run — the dump infrastructure is armed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+38.3 KB
(920%)
native/shared/tests/golden/many_point_lights_clustered_scene.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Clear current-frame profiler state when starting a fresh session.
set_enabled(true)resets rolling history, but notframe,open_cpu,next_query,pending_gpu, orbudget_warned. If an external caller toggles off→on beforeframe_endruns, old in-flight samples can be folded into the first “fresh” frame, and the GPU budget warning stays suppressed from the previous session.Proposed fix
pub fn set_enabled(&mut self, on: bool) { if on && !self.enabled { // Fresh measuring session: without this, stats captured before // a disable (potentially under a different feature set) show // until the rolling window refills and skew the first seconds // of every new session. + self.open_cpu.clear(); + self.frame.clear(); self.rolling.clear(); + self.next_query = 0; + self.pending_gpu.clear(); + self.budget_warned = false; self.frame_total_cpu_us = [0.0; ROLLING_FRAMES]; self.frame_total_gpu_us = [0.0; ROLLING_FRAMES]; self.histogram_idx = 0; self.histogram_filled = 0; }📝 Committable suggestion
🤖 Prompt for AI Agents