perf(memory): VEH fault guard for MinGW seh_read#118
Conversation
Guard MinGW seh_read_bytes/read_ptr_unsafe with a process-wide vectored exception handler instead of a per-call VirtualQuery: zero-syscall success path recovered via non-unwinding __builtin_setjmp/longjmp, also closing the stale-cache unguarded dereference. Per-thread guard via an allocation-free Win32 TLS slot, drained before handler removal, with a VirtualQuery fallback for install failure and 32-bit builds. MSVC __try path unchanged.
|
Warning Review limit reached
More reviews will be available in 44 minutes and 7 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR replaces MinGW memory read fault handling from per-region ChangesMinGW VEH-Based Memory Read Safety
🎯 4 (Complex) | ⏱️ ~60 minutes Possibly Related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/misc/hot-path-memory.md`:
- Around line 117-120: Update the MinGW documentation to explain that
veh_read_bytes in src/memory.cpp uses the VEH guarded-copy only when
ensure_veh_installed() succeeds (i.e., s_veh_handle is non-null); if handler
installation fails or on 32-bit MinGW (! _WIN64) it falls back to
virtualquery_validated_copy (VirtualQuery-validated copy), so seh_* reads are
best-effort and may use VEH→VirtualQuery fallback rather than always using the
process-wide VEH.
In `@tests/test_memory.cpp`:
- Around line 2339-2374: The test GuardedReadsSurviveConcurrentShutdown races
the shutdown/init loop against readers so it may never exercise the guarded-read
path; modify the test to wait until at least one successful good-path read and
one faulting-path read have been observed before starting the 12-cycle loop.
Instrument the reader lambda that calls Memory::read_ptr_unsafe to increment two
std::atomic<int> counters (e.g., seen_good and seen_fault) depending on whether
the target was the committed page or the freed page, then before the first call
to Memory::shutdown_cache()/Memory::init_cache() spin-wait or block until
seen_good.load() > 0 && seen_fault.load() > 0 (or use a condition_variable) so
the shutdown exercises the drain path; keep the rest of the teardown (stop,
join, final EXPECT_EQ) unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ea12cab4-646c-402d-a3ac-eacf8ff9d1dd
📒 Files selected for processing (10)
AGENTS.mdREADME.mddocs/analysis/memory_veh_bench_v3.x/README.mddocs/misc/hot-path-memory.mddocs/misc/rtti-walker.mdinclude/DetourModKit/memory.hppsrc/memory.cpptests/bench_memory.cpptests/test_memory.cpptests/test_scanner.cpp
Wait for a live good-path and faulting-path guarded read before the shutdown/init loop so it exercises the in-flight drain rather than possibly racing ahead of any guarded read. Also clarify in hot-path-memory.md that MinGW seh_* takes the VEH guarded-copy path only when the handler installed, and falls back to a VirtualQuery-validated copy on install failure or 32-bit builds.
Summary
On MinGW the
seh_readfamily (seh_read_bytes,read_ptr_unsafe, the pointer-chain reads) paid aVirtualQuerysyscall on every guarded read because GCC has no zero-cost frame-based SEH. This replaces that with a single process-wide vectored exception handler, so the success path is a guarded copy with no syscall and a read fault is recovered instead of crashing the host. It also closes a stale-cache unguarded dereference that could crash on a page reprotected out from under the cache. The MSVC__trypath is unchanged.Notes
Summary by CodeRabbit
Documentation
Performance
Tests