Make -p (and cluster-stream walkers) fast: cache reads, skip RBin strings - #19
Merged
Merged
Conversation
…ings r2flutter -p burned ~100% CPU for several seconds on large libapp.so/App images. Two bottlenecks were responsible: 1. read_mem() went through the full radare2 IO stack (banks, caches, interval trees, mmap seek/lseek) once per byte, because the cluster stream decoders read one byte at a time while walking the whole modern_parse_cluster_meta stream twice. read_mem() now serves reads from a forward-sliding 1 MiB window cached in DartCtx, collapsing millions of IO calls into a handful. The cache is scoped to a single command and freed in dart_obf_fini. A request is only served when fully contained in the window; a failed windowed refill falls back to an exact read, so semantics are unchanged. 2. The standalone tool let r_core_bin_load run RBin's whole-file string scan (the single largest profile entry) even though r2flutter never uses RBin's string list. The CLI now sets bin.strings=false before loading. The core plugin path is untouched. On test/bins/android/mafia/libapp.so (14 MB), -p drops from ~2.6s to ~0.05s (~50x) with byte-identical output across all actions; the shared read cache also speeds up the heavier -x/-z walkers. Full custom testsuite (35/35) still passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RzwE1yCFnmG27vED2CpkR3
The help test drifted from the actual program output and failed CI: - Standalone usage (-h) gained the "(-ii same as -i)" note on -i and a new "-ie[jr*], -E[jr*] Print Dart code entrypoint" line that the EXPECT block never picked up. - The core plugin help lists -h once (grouped with -v/-V), but the EXPECT had a duplicate "-h show this help" line in the middle of the alphabetical list, in both plugin-help blocks. Regenerated the expected output to match the current binaries; all three db/extras tests pass under r2r. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RzwE1yCFnmG27vED2CpkR3
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
r2flutter -p burned ~100% CPU for several seconds on large libapp.so/App
images. Two bottlenecks were responsible:
read_mem() went through the full radare2 IO stack (banks, caches,
interval trees, mmap seek/lseek) once per byte, because the cluster
stream decoders read one byte at a time while walking the whole
modern_parse_cluster_meta stream twice. read_mem() now serves reads from
a forward-sliding 1 MiB window cached in DartCtx, collapsing millions of
IO calls into a handful. The cache is scoped to a single command and
freed in dart_obf_fini. A request is only served when fully contained in
the window; a failed windowed refill falls back to an exact read, so
semantics are unchanged.
The standalone tool let r_core_bin_load run RBin's whole-file string
scan (the single largest profile entry) even though r2flutter never uses
RBin's string list. The CLI now sets bin.strings=false before loading.
The core plugin path is untouched.
On test/bins/android/mafia/libapp.so (14 MB), -p drops from ~2.6s to
~0.05s (~50x) with byte-identical output across all actions; the shared
read cache also speeds up the heavier -x/-z walkers. Full custom
testsuite (35/35) still passes.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01RzwE1yCFnmG27vED2CpkR3