Repository navigation
fix(mcp): skip unreadable regions before splitting scans - #128
Conversation
On Windows the region snapshot spans the whole address space, MEM_FREE and MEM_RESERVE ranges included (~128 TiB on a 64-bit target). _run_batched_scan cut all of it into scan_batch_bytes pieces, about two million batches at the 64 MiB default, so scan_value and scan_pattern spent their whole budget before reaching the heap. Leave unreadable regions out before split_regions/batch_regions in _run_batched_scan and find_pointer_paths. Every backend's scan already drops them through default_scan_filter, and scan_pointer_paths keeps only readable regions, so results do not change. Fixes JeanExtreme002#127 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are recorded for the change filtering unreadable memory regions before scan batching and pointer-map splitting.
No open issues 🎉
What changed in this PR
Fixes #127 by filtering unreadable memory regions before MCP scans split and batch them, preventing Windows free and reserved address space from consuming the scan budget before reaching readable memory.
Changes:
- Filters unreadable regions before value/pattern scan batching and pointer-map splitting.
- Adds regression tests confirming unreadable regions produce no scan batches or pointer-map pieces.
- Leaves memory-region listings and session snapshots unchanged.
| File | Description |
|---|---|
| tests/mcp_server/test_toolset.py | Adds regression coverage for large unreadable regions in scans and pointer maps. |
| PyMemoryEditor/mcp/toolset.py | Filters unreadable regions before splitting and batching scan work. |
Review effort: Balanced
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #128 +/- ##
==========================================
- Coverage 93.04% 93.02% -0.02%
==========================================
Files 43 43
Lines 4671 4672 +1
==========================================
Hits 4346 4346
- Misses 325 326 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Hi, @StupidDev1337. Thanks a lot for the contribution, and for the detailed write-up and the reproducer in #127! I went through the change and it looks good to me: the library already drops unreadable regions on every backend, so filtering them before splitting doesn't change any results, and it fixes the timeout on 64-bit Windows targets. CI is green on Windows, Linux and macOS as well. I'm going to merge it. ❤️ |
Patch release carrying #128: the MCP server's scan_value, scan_pattern and find_pointer_paths now leave unreadable regions out before cutting the region snapshot into pieces. On a 64-bit Windows target the snapshot spans the whole address space, so 3.4.1 spent its whole scan budget on about two million empty batches and returned nothing (#127). Co-authored-by: Claude Fable 5.2 <noreply@anthropic.com>
Why is this PR necessary, what does it do?
Fixes #127. On 64-bit Windows targets,
scan_valueandscan_patternran out of the 30 s budget before they reached the heap.MEM_FREEandMEM_RESERVEranges included._run_batched_scancut all of that intoscan_batch_bytespieces. At the 64 MiB default that is about 2 million batches for ~128 TiB.This PR leaves unreadable regions out before
split_regions/batch_regions:_run_batched_scanfilters the snapshot to readable regions first. Unreadable regions can never hold a match, and every backend's scan already drops them throughdefault_scan_filter, so the results do not change.find_pointer_pathsapplies the same filter before cutting regions for the pointer map.scan_pointer_pathsalready keeps only readable regions itself, so the map does not change. It just no longer builds millions of pieces first.list_memory_regionsand the session's region snapshot are untouched.How it was tested
tests/mcp_server/test_toolset.py(TestHugeRegionsAreScannedInPieces) use a fake target with a 1 MiB unreadable region below its two readable ones.flake8 PyMemoryEditor testsandmypy PyMemoryEditorreport no issues.pytest tests) on Windows 11 x64, Python 3.13.14, with thespeedextra: 1832 passed, 28 skipped, 1 failed.tests/process/test_foreign_process.py, and it fails the same way on unmodifiedmain.sys.executableis the venv launcher, which starts the real interpreter as a child, so the test opens the launcher's pid (WinError 299).--scan-batch-bytes:scan_valuereturns the counter withcount: 1,partial: false,elapsed_seconds: 0.002;count: 0,partial: true,elapsed_seconds: 30.122.Checklist (complete all items):
References:
Fixes #127
Notes:
MemoryRegion.is_readable, so it is platform-independent. I could only run it on Windows; CI will cover Linux and macOS.🤖 Generated with Claude Code