mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 06:45:22 +00:00
[GH-ISSUE #1389] [Design] Add rsleigh as a headless static-analysis provider candidate #483
Open
opened 2026-10-15 18:25:26 +00:00 by bsakaguchi
·
8 comments
No Branch/Tag specified
main
codex/procedure-reference-stacked
release-please--branches--main--components--rea-agents
release-please--branches--main--components--rea-agents--release-notes
codex/kuna-independent-retry
codex/byte-search-overlay-coverage
codex/open-failure-target-receipt
codex/kuna-xref-evidence
codex/ghidra-ambiguous-procedure-recovery
codex/function-source-bundle
codex/trace-function-integration-prototype
codex/snapshot-source-closure
codex/recorded-evidence-array-pages
codex/evidence-recovery-redesign
codex/trace-feature-address-scope
codex/call-discovery-scope
codex/ghidra-literal-candidate-evidence
codex/decompile-directory-independent-retry
codex/retry-provenance-base
codex/value-flow-capability-experiment
codex/ghidra-containing-instruction
cursor/readme-discord-button-ef9f
dependabot/github_actions/actions/setup-node-7.1.0
dependabot/github_actions/actions/upload-artifact-7.0.2
dependabot/npm_and_yarn/npm-minor-and-patch-d8d97ce6df
codex/kuna-1989
fix/8559-native-ui-fixture-ownership
fix/8555-go-verifier-mcp-ownership
codex/provider-capability-recovery
fix/8642-rizin-target-stdin
codex/ghidra-memory-effect-scope
codex/ghidra-annotation-entry-selector
codex/ghidra-readonly-recovery
codex/ghidra-regex-verifier-recovery
codex/evidence-discovery-view-guidance
fix/8545-bulk-append-overflow
fix/8428-navigation-refusal-alternatives
codex/address-context-recovery
codex/matching-member-limitations
codex/unknown-scope-contract
codex/evidence-view-guidance
feat/8373-native-trace-views
codex/ghidra-snapshot-verifier-binding
codex/elf-export-visibility
codex/evidence-view-recovery
codex/native-reference-cli-help
codex/provider-candidate-observation-scope
codex/kuna-session-verification
codex/ghidra-switch-lifetime-guidance
codex/pseudocode-paging-discovery
codex/clarify-evidence-view-support
codex/kuna-xrefs-selector-recovery
codex/context-capacity-recovery
codex/evidence-closure-large-links
codex/same-function-evidence-identity
codex/ghidra-verifier-inspected-jdk
codex/audit-guided-workflows
codex/crash-prompt-retained-dossiers
codex/analysis-view-error-recovery
codex/kuna-verifier-target-selection
codex/ghidra-selected-project-call-coverage
codex/docs-native-analysis-scope
codex/ghidra-java-socket-boundary
codex/ghidra-retained-snapshot-verifier
codex/ghidra-search-inventory-facts
fix/8284-zero-argument-parameter-bindings
fix/8198-ui-action-handler-offset
fix/8257-elf-entry-label-identity
fix/8304-deferred-output-schema-projection
fix/8277-call-path-computed-target-uncertainty
fix/pr-8089-conflicts
fix/ci-static-duplicate-export
dependabot/npm_and_yarn/lint-staged-17.6.0
dependabot/github_actions/actions/download-artifact-8.0.2
dependabot/npm_and_yarn/write-file-atomic-8.0.0
dependabot/npm_and_yarn/canonicalize-5.1.0
dependabot/github_actions/actions/cache/restore-6.1.0
dependabot/npm_and_yarn/toon-format/toon-4.4.0
dependabot/github_actions/actions/deploy-pages-5.0.1
codex/review-fixes-pr-2403
codex/review-fixes-pr-2400
codex/process-terminal-width
codex/test-brittleness-cleanup
verify/7167-browser-connect-macos
fix/7167-browser-connect
feat/native-matching-allowance-setting
feat/browser-scenario-dry-run
test/managed-caller-parameters-20261024
codex/parser-fortythird-boundaries
fix/6926-pinvoke-platform-decorations-20261023
fix/6889-har-body-encoding-20261023
fix/6888-sqlite-schema-budget-20261023
fix/dependency-security-gates-6708
cursor/evidence-overwrite-rebase-b4ac
feat/4057-verify-native-exports
fix/windows-acl-observer-overhead-20261022
cursor/erlang-beam-restack-4476
cursor/pe-certificate-review-bf32
fix/6116-javascript-application-fs-errors
fix/6061-unmapped-runtime-script-unknown
feat/browser-scenario-summary
fix/pe-certificates
codex/verify-3407
cursor/rebase-5699
cursor/rebase-5352
cursor/rebase-5600
cursor/fix-cli-schema-omission-10a8
codex/audit-hopper-shutdown-reasons-20261021
fix/demangle-swift-omitted-record
fix/nib-boolean-value-types
cursor/cancellation-partial-observation-a5ac
fix/ib-object-limit-reasons
fix/electron-fuse-limit-advice
fix/kuna-doctor-dangling-cache
fix/fixed-budget-refusal-advice
fix/js-ipc-listener-dedup
fix/js-return-member-provenance
fix/dmg-integrity-retry-advice
fix/ida-doctor-readiness
fix/kuna-version-probe-output-drain
fix/legacy-swift-runtime-name-matching
fix/dylib-lazy-load-commands
fix/browser-scenario-startup-cancel
fix/swift-nested-punycode-classification
fix/compare-unselected-scopes
fix/objc-method-budget-coverage
fix/dmg-mounted-root-observations
audit/ci-tests-20261019-round2
release/6.7.0
fix/wabt-cleanup-retry-resolution
fix/electron-fuse-elf-pe-architecture
fix/native-plist-descriptor-ownership
fix/kuna-caller-cleanup-ownership
experiment/atomic-codemode-20261016
review/first-contributor-3776
fix/call-resolution-full-read-cycles
fix/member-mutation-selection-repeat
experiment/atomic-re-tools-20261015
perf/member-mutation-lazy-origins
perf/static-network-mutation-index
fix/hopper-startup-lifecycle
audit/3050-windows-proof-20261015
feat/windows-window-capture-2183
audit/3049-windows-proof-20261015
audit/3735-macos-fixtures-20261015
fix/batch-decompile-null-pseudocode
fix/kuna-inventory-honors-jobs
experiment/browser-codemode-tool-design-20261015
fix/hopper-clean-runtime-argv
codex/review-2049-27f1b367
review-fixes/pr-2787-routing
fix/3360-scoped-this-emitters
fix/3367-replaced-global-effects
fix/3838-compact-any-value-items
test/hopper-download-probe-20261015
codex/windows-runtime-creation-red-green-20261015
codex/windows-readonly-root-red-green-20261015
codex/windows-root-share-red-green-20261015
codex/exp-1685-win-mcp-startup
codex/bug-sweep-20261015
investigate/2190-windows-package-phases
investigate/3543-macos-cli-deadline
perf/3281-reverse-tools-feedback-quality
fix/3406-hopper-doctor-fixture
fix/3341-wrapper-require-test-context
fix/3301-owned-uninstall-fixtures
fix/3164-compiler-input-ownership
fix/pcap-cleanup-stdout-newline-20261014
perf/interface-builder-summary
codex/review-fixes-pr-1977
fix/ghidra-effective-jvm-platform
fix/docs-turkish-rust-link-20261013
fix/main-maintenance-ci-20261010
fix/recover-binary-session-process-effects
codex/review-fixes-pr-2457
codex/ci-required-cancellation-gate
fix/main-format-baseline-20261013
fix/setup-preserve-entry-fields
cursor/restore-main-checks-1ffc
fix/ghidra-bridge-hashmap-import
codex/shared-ci-jadx-json-default-20261013
codex/shared-ci-ghidra-test-groups-20261013
codex/shared-ci-java-fixture-format-20261013
codex/fix-intrinsic-invocation-boundaries
test/release-preflight-reusable-jobs
test/js-parameter-provenance-expectation
fix/linux-hopper-verification-current
test/2419-ghidra-elf-probe-size
followup/pr-1544-native-ida
codex/fold-pr-2230-contribution
docs/readme-responsible-use
fix/issue-2064
fix/issue-2050
fix/issue-2053
fix/issue-1968
fix/issue-1945
experiment/codemode-bridge-20261011
fix/tool-effects-negative-wording-1904-20261012
fix/1842-electron-interop-provenance
feat/recover-javascript-multi-input
refactor/website-i18n-prep
fix/nativeaot-pe-virtual-extent
fix/browser-verifier-ci-hang
fix/pe-resources-input-selection
docs/beginner-friendly-guides
docs/beginner-setup-guide
fix/javascript-analysis-worker-1563
fix/1649-ghidra-duplicate-names
fix/javascript-export-keys-integration-1369
test/maintenance-boundary-contracts-20261011
review/javascript-export-keys-1369
review/process-live-progress-1483
test/javascript-1495-growth-ratio
fix/ci-escape-timing
docs/normalized-terminal-geometry-1450
release/6.3.0
archive/release-6.3.0-pr1381
release/6.2.0
fix/electron-preload-dynamic-override
fix/javascript-self-referential-bundler-edges
release/6.1.0
cursor/grok-client-cherry-pick-0b56
feat/signature-posture
feat/dyld-shared-cache
feat/artifact-integrity-policy
feat/pkg-inventory
release/6.0.0
chore/sync-release-5.0.0
release/5.0.0
cursor/cloud-agent-node-787e
fix/javascript-xhr-open-endpoints
review/pr-711-realpath-fallback-wording
cleanup/replay-confinement
codex/test-suite-performance
codex/issue-foundations
codex/address-open-issues-2026-07-20
agent/javascript-vite-rollup-esbuild-adapters
agent/process-cleanup
agent/triage-integration
agent/unknown-commands-registry
feat/mcp-identity-metadata
morlvps/issue_cleanup
codex/installer-redesign
morl/roadmap-investigation-core
morl/roadmap-investigation-docs
release-please--branches--main--components--rea
rea-agents-6.8.0
rea-agents-6.7.0
rea-agents-6.6.0
experiment/atomic-codemode-wait-runtime-20261016
rea-agents-6.5.0
rea-agents-6.4.0
rea-agents-6.3.0
rea-agents-6.2.0
rea-agents-6.1.0
rea-agents-6.0.0
rea-agents-5.0.0
rea-agents-4.1.0
rea-agents-4.0.1
rea-agents-4.0.0
rea-agents-3.2.1
rea-agents-3.2.0
rea-agents-3.1.0
rea-agents-3.0.0
rea-agents-2.7.0
rea-agents-2.6.0
rea-agents-2.5.1
rea-agents-2.5.0
rea-agents-2.4.0
rea-agents-2.3.0
rea-agents-2.2.0
rea-agents-2.1.0
rea-agents-2.0.0
rea-agents-1.7.0
rea-agents-1.6.0
rea-agents-1.5.0
rea-agents-1.4.0
rea-agents-1.3.0
rea-agents-1.2.0
rea-agents-1.1.0
rea-agents-1.0.0
rea-agents-0.5.0
rea-agents-0.4.0
rea-agents-0.3.0
rea-0.2.1
rea-0.2.0
Labels
Clear labels
area: bridge
area: bridge
area: build
area: build
area: build
area: cli
area: domain
area: evidence
area: mcp
area: native
area: providers
area: runtime
area: server
area: setup
area: tests
bug
design
documentation
enhancement
enhancement
enhancement
experiment
help wanted
i18n
invalid
P0: critical
P1: high
P2: medium
P2: medium
P2: medium
P3: low
performance
provider-request
pull-request
Mirrored from GitHub Pull Request
question
roadmap
triage
No labels
area: bridge
area: bridge
area: build
area: build
area: build
area: cli
area: domain
area: evidence
area: mcp
area: native
area: providers
area: runtime
area: server
area: setup
area: tests
bug
design
documentation
enhancement
enhancement
enhancement
experiment
help wanted
i18n
invalid
P0: critical
P1: high
P2: medium
P2: medium
P2: medium
P3: low
performance
provider-request
pull-request
question
roadmap
triage
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set.
Reference
morluto/rea#483
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @ShaneBreazeale on GitHub (Oct 10, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1389
Before submitting
Decision needed
Should REA accept rsleigh as a deep binary-analysis provider candidate? If so, should the provider call the rsleigh CLI once per operation, or keep an
rsleigh --mcpchild process open for a target session?rsleigh is a pure-Rust static analyzer. It lifts instructions with Ghidra SLEIGH specifications (P-code), recovers SSA, and decompiles. It needs no JVM, GUI, license, or network access. It supports x86-64, x86-32, AArch64, ARM32, MIPS32, and RISC-V 64 in PE, ELF, and Mach-O files. That would give REA a headless, read-only native provider that can run in CI or sandboxes where Ghidra, IDA, or Hopper are unavailable.
Context and evidence
Observed (rsleigh at main after #5/#6):
rsleigh --capabilities --json(rsleigh.capabilities/v1) is generated from the same typed contracts that validate every agent invocation. For each operation it lists the flag kinds, effects (reads_binary,writes_cache, ...), limits, examples, and support per frontend and architecture, with quality reported separately from availability.rsleigh.card/v2,rsleigh.ssa-slice/v3,rsleigh.agent-brief/v1, ...) withstatusok/partial/failed, exit codes 0/2/1, and stableerror_codevalues. Results that are partial or truncated, and boundaries that could not be resolved, are reported explicitly rather than dropped.rsleigh.evidence/v1) are content-addressed and carry subject identity (binary SHA-256, format, architecture, image base) and producer identity (build, analysis profile). Bundles of them can be verified offline. Parts of this design were adapted from REA's evidence, unknown, and comparison models, as recorded in a design note.rsleigh --mcpservescapabilities,agent-brief,card,ssa-slice, andverify-bundleover stdio. Its tool schemas are generated from the same catalog, and tests check that its results match the CLI.Observed (REA, current main):
AnalysisOperationis a closed union, and #740 lists "do not accept arbitrary unknown external tool catalogs" as an invariant. So rsleigh's MCP server cannot simply be mounted; an integration has to be a typedAnalysisProviderCandidatethat maps onto REA's canonical contracts.Derived: rsleigh's existing outputs could supply most of the provider interface:
inspectAvailabilityfrom--version --json.inspectTargetSupportfrom the catalog's frontends and architectures.resolveAnalysisProfilefrom the build and profile identity in evidence records.capabilities()effects and limitations from the catalog.Inference, unverified: a read-only subset of the official tools looks feasible:
list_procedures,search_procedures--searchprocedure_info--cardprocedure_assembly,read_function_instructionsprocedure_pseudo_code--card --decompileprocedure_callers,procedure_callees--xrefslist_stringsMutation and UI-state tools (
set_comment,set_address_name, bookmarks,goto_address/current_*) would be reported unavailable. I have not run REA's conformance or real-provider lanes against rsleigh.Boundary and invariants
partialstatus and unresolved boundaries map to REA limitations or unknowns and must not be upgraded to complete results. Its P-code-backed evidence would attach to REA's evidence ledger with rsleigh's provider identity and profile.Options and tradeoffs
rsleigh FILE --card --json ...per operation). This is stateless, cleanup and cancellation are simple, and every call has a versioned JSON contract. The cost is parsing the binary on every call; rsleigh's--analysis-cache DIRavoids repeating SSA work.rsleigh --mcpchild process for each target session. This uses one connection, but today it gives no extra state: rsleigh MCP calls run one at a time, re-read the target, and do not act on cancellation notices (the process would have to be terminated). It would also put a second protocol layer inside a provider.Option 1 looks like the smallest fit with REA's owned-process and contract model; option 2 becomes worthwhile only if rsleigh gains state that persists across calls in a session.
Success criteria and open questions
The decision is settled by maintainer agreement on whether an rsleigh provider is in scope and which transport to use. Implementation would then start with a PR containing an
AnalysisProviderCandidate, its composition wiring, and the matching provider lane.Open questions:
capabilities()?cargo install rsleigh) or from release binaries?References
src/application/AnalysisProvider.ts,src/contracts/officialToolContracts.ts, #740@CassieFox23 commented on GitHub (Oct 10, 2026):
TL;DR: Of nine claims I checked on a Linux build of rsleigh, seven held, one held with a gap, and one did not hold in two cases. On an idle machine, rsleigh was far faster than REA with Ghidra, but its decompiler was wrong or short on 3 of 4 functions. I also re-read the REA provider code on main, and it matches the issue, with one detail to add about profile versions.
What I tested
I used rsleigh (Apache-2.0) at commit 0748bd6a7. That commit is the merge of ShaneBreazeale/rsleigh#6. Master still pointed there on 2026-10-10. I tested x86-64 ELF files only, against REA (MIT) 6.3.0 with Ghidra (Apache-2.0) 12.1.4. I read REA main at
6db97d516for the code claims, and I ran nothing from REA against rsleigh.Claims I checked
--capabilities --jsonisrsleigh.capabilities/v1--version --jsonerror_codeon failureverify-bundleworks offline--mcpserves 5 toolsThe gap: I ran a card on the sqlite3 shell with
--deadline-ms 1. The card exits 1 with statusfailed, but has no top-levelerror_code. The error text is "no decodable instructions at requested address", which is not the cause. The real cause sits indiagnostics, asexecution_limitwith reasondeadline.Speed and memory
These are medians of 5 runs on an idle machine, with nothing else of mine running. Load average is how many jobs were running or waiting for a CPU thread, on average, out of 24 threads. It was between 1.3 and 2.0 at the start of every run. The targets were copies of
trueandlsfrom coreutils 9.10 (GPL-3.0-or-later). I also used thesqlite3shell from SQLite 3.51.2 (public domain) and my own small C program, rebuilt for this run. Each cell shows wall time, then peak memory of the largest process, in MiB.maintruestublsfunctionsqlite3_freeThis is not a fair race. Each REA call ran a full, fresh Ghidra import of the whole file. The rsleigh card looks at one function. The brief looks at the whole file, but it stops at 25 functions. For
true,lsandsqlite3it exited 2 with statuspartialon every run, with 25 of 143, 641 and 5,931 functions. All 20 rsleigh cards saidok, and all 20 REA runs returned JSON with a result.Decompile output
Three of four functions came out wrong or short. My test program's
mainhad the wrong structure. Thelsfunction lost a cold block, andsqlite3_freecame back empty. Both of those still saidok, with no warning. Thetruestub is a one-instruction jump into libc, so I do not count it. Both tools named itdcgettext. Ghidra showed the jump as a one-line call, and rsleigh showed nothing. The rsleigh text for my test program'smainand for thelsfunction also changed a little from run to run on the same file. I opened ShaneBreazeale/rsleigh#7 for that. Details are in the "Decompile output" fold below.REA code I read (main
6db97d516)AnalysisOperationis a closed list of tool names, so rsleigh's MCP server cannot be mounted as it is. The issue says the same.--version --jsonfitsinspectAvailability.version_unresolved. The profile must also carry the provider's version string. rsleigh gives its version and a build ID up front. I did not check if the rest of its profile can be built before a run.procedure_callers.autoreturns anambiguouserror and picks neither.src/composition/binary.ts, so a fourth needs an entry there. The provider SDK issues #45 and #371 were closed on 2026-07-20 as out of scope for now, with in-tree providers first.7a0c80085.Not run
--xrefs,--search,--index,compareand the question tools.ssa-slice,verify-bundleand cancellation.Thanks, ShaneBreazeale, for the clear post and for the design note behind it. I take no side on the design question.
Timing ranges (minimum to maximum of 5 runs)
maintruestublsfunctionsqlite3_freeI took 5 runs of each cell in turns, one process at a time. Before each run I waited while the one-minute load average was over 2.0. That happened before 7 of 60 runs, for 15 or 30 seconds each. No run started above 2.0. I ran one untimed warm-up of each command first. The REA warm-up took 8.3 s on my test program, about half a second over the timed runs. REA left no files in its temp folder between runs. No run was killed by a signal or timed out.
Decompile output
main: Ghidra matched the source. rsleigh had the right calls and strings. But rsleigh readargcas if it wereargv, wrote a garbled hash loop, and lost two of the three return values. I rebuilt this program for this run, and it may differ from the one I used in my first check.lsat0x5580: the function jumps to a cold block at0x598f. That block callsgetenv("TERM"). rsleigh left it out of the body and the output. The card still saidok, with no warning.sqlite3_freeat0x42960: rsleigh gave an empty body and statusok, with no warnings. Ghidra gave about 30 lines.truestub is a one-instruction jump into libc. Both tools named itdcgettext. Ghidra's body is one call todcgettext. The rsleigh body is empty. I do not count this stub in the "3 of 4".truestub and forsqlite3_freenever changed. The text for my test program'smaintook 3 different forms, and thelstext took 5. The structure stayed the same each time. A later check of 20 runs each gave 4 forms formainand 10 forls.The README says the decompiler is not stable yet. I did not compare P-code.
Build (relevant to open question 3)
build.rs. The generate step only writes intogenerated/*/outinside the clone.Two small notes
imagebasefield held the address of the.initsection. Forlsthe field said0x33c, but the load base is 0. I don't know if that is on purpose.--xrefs,--searchand string recovery. Those modes are not in the capabilities catalog, and I did not test them.REA source lines at
6db97d516src/application/AnalysisProvider.tslines 24 to 31.src/ghidra/GhidraInstallation.tslines 729 to 740, with the 5 second limit at line 736.inspectAvailabilityis insrc/ghidra/GhidraProvider.tslines 88 to 120.src/application/AnalysisProvider.tslines 130 to 133, andsrc/application/binary/AnalysisProviderEvaluation.tslines 80 to 102. The version string must be non-empty:src/domain/analysisProfile.tslines 10 to 14.src/ghidra/GhidraProviderCapabilities.tslines 20 to 23. Windows Ghidra marks edits unavailable at lines 192 to 199.procedure_callers:src/ida/IdaProviderCapabilities.tslines 48 to 53.ambiguousunderauto:src/application/binary/AnalysisProviderRegistry.tslines 318 to 319. The default selector isauto, insrc/config/environment.tsline 12.src/composition/binary.tslines 25 to 32.Commands
Build, from the rsleigh clone. The fetch step needs the network. The other two run offline.
rsleigh card, and REA with Ghidra. For PIE files, the Ghidra address is the rsleigh address plus 0x100000. My test program is not a PIE, so it uses the same address in both tools.
Each timed run was wrapped as
( ulimit -c 0; /usr/bin/time -o FILE -f "%e %M %x" timeout N ... ). The%Mvalue is in KiB, and the tables show it divided by 1024.My test program was built with
gcc -O1 -no-pie, not stripped. It checksargc, returns 2 with no argument, hashesargv[1]in a loop, and returns 0 or 1 on the hash.Test setup
6db97d516for the code reading🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊
@ShaneBreazeale commented on GitHub (Oct 11, 2026):
@CassieFox23, following up on your report. Here is where each point stands.
Fixed on master
main: the h*33 loop,% 7, and returns 2/1/0 now print correctly (#10, #11).lscold block and emptysqlite3_free:.coldparts are decoded into their function and tail calls are recovered. Partial status now reports unresolved control flow (#10).truestub: recovered as a tail call (#10).6c429ba, now on master.error_code: fixed in #9.Still open
imagebaseforlsshows 0x33c instead of the load base. Fixing it changes evidence IDs for ELF and Mach-O, so we're waiting on a maintainer decision.--xrefsand--search. Both work on our Debian builds, but they're legacy CLI modes and not in the capability catalog.Not verified yet
ls0x598f,sqlite3_free0x42960) are unconfirmed. Could you rerun on your binaries and tell us what you see? That would settle it.Thanks for the careful report and measurements.
@ShaneBreazeale commented on GitHub (Oct 11, 2026):
@CassieFox23, an update on the two items that were still open, and a correction to my last comment.
imagebaseis fixed in ShaneBreazeale/rsleigh#13.PT_LOADpage, and Mach-O reports the__TEXTaddress. These are the values Ghidra shows. PE is unchanged.ls:0x33c→0x00x401254→0x4000000x100000328→0x100000000Correction about
--xrefs. I said it works on our Debian builds. When I looked more closely,--xrefs sqlite3_freehad three bugs:func_c3b500000as a callee. That is an internal temporary ID, not a function. The same bad name appeared in the normal decompile output.All three are fixed in ShaneBreazeale/rsleigh#12.
--xrefs sqlite3_freenow prints nothing to stderr and finds 321 callers at 837 call sites. objdump counts 895 calls, and the rest are in functions longer than the 4 KiB scan window.Still open
--xrefsand--searchare still not in the capabilities catalog. The mapping table in the issue relies on modes that the agent contract does not describe yet.ls0x598f,sqlite3_free0x42960) are still unconfirmed. A rerun on your binaries would settle it, if you have time.One more fix: in my last comment, the bare numbers #8 to #11 point at REA issues. They mean ShaneBreazeale/rsleigh#8, ShaneBreazeale/rsleigh#9, ShaneBreazeale/rsleigh#10 and ShaneBreazeale/rsleigh#11.
@CassieFox23 commented on GitHub (Oct 11, 2026):
TL;DR: I reran your list on my Fedora files. Five items are fixed. The loop test in my test
mainstill prints wrong.Thanks, Shane, for asking. I used master at 8f75176f1 (ShaneBreazeale/rsleigh#11). The
lsaddress (0x598f) is real on my box. Thesqlite3_freeaddress (0x42960) is in the sqlite3 command-line program, not in the library. In Fedora'slibsqlite3.so,sqlite3_freesits at 0x25f0. So your 3.53.4 library and my file are different files.What I see on master
main% 7and returns 2, 1 and 0 all print. The loop ends onwhile (lVar1 % 7). The assembly loops until the next byte is zero.lscold block at 0x598fgetenv("TERM")is in the output.sqlite3_freeat 0x42960truestub at 0x680return dcgettext();.execution_limit.ok. I did not sweep other functions.Before,
lsgave 10 different texts in 20 runs.Your second comment covers
--xrefs. On Fedora, master showed the same problems:--xrefs sqlite3_freeonlibsqlite3.soprints 4 panic lines on master. It finds 0 callers.--search sqlite3_freeon the same file crashes with a stack overflow (exit 134). That is a new problem, not on your list. It happens on master and on #12 too.--search TERMonlsworks.I also tested both pull requests before they merged.
imagebaseon all 7 Fedora files I tried. Forlsit goes from 0x33c to 0x0.Not run
lsandsqlite3functions for partial status.Raw numbers
main0x400480ls0x5580sqlite3_free0x42960true0x680lsfunction now spans 0x5580 to 0x5a36. That is 1,208 bytes. Before it was 758 bytes.lstext is cut at 4,096 of 6,096 bytes. The card says so.// switch(...)comments in thelstext show a garbled dash. I did not trace the cause.mainis the short program from my 10-10 run, built withgcc -O1 -no-pie. Its sha256 matches the 10-10 build.Commands
Each build:
cargo run --locked --release -p rsleigh-generate, thencargo build --locked --release -p rsleigh-cli.Test setup
🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊
@ShaneBreazeale commented on GitHub (Oct 11, 2026):
@CassieFox23, a follow-up on the two items I left open.
--xrefsand--searchare now in the capabilities catalog (ShaneBreazeale/rsleigh#15).--jsonthey emitrsleigh.xrefs/v1andrsleigh.search/v1.partial(exit 2) and gives atruncated_scanscount. Before, the missed calls were silent. On Debianlibsqlite3, 28 functions are over the limit, which explains the gap to objdump.I checked your Fedora addresses on the Fedora 44 packages:
ls0x5580→0x598fmatchescoreutils-9.10-5.fc44(the update). It does not match the-3release build.0x42960is in/usr/bin/sqlite3fromsqlite-3.51.2-1.fc44and-2.fc44, not inlibsqlite3. That binary is stripped. Inlibsqlite3.so,sqlite3_freeis at0x25f0.On current rsleigh master, with your card command:
ls0x5580: the cold block is now in the body, includinggetenv("TERM").sqlite30x42960: the body is no longer empty. It shows thesqlite3_freeshape: the null check, then the mutex, size accounting, and free hooks..data(call [0x1dd0a0]), but rsleigh prints them as direct calls such asfunc_1dd0a0(). They should read as calls through the pointer. I'll track that separately.@CassieFox23 commented on GitHub (Oct 15, 2026):
TL;DR: I timed rsleigh (Apache-2.0) on three files, next to kuna (Apache-2.0) and Ghidra (Apache-2.0). It listed functions and decompiled one function in under 2.5 seconds on all three, even on the 10 MB file. Its decompile-everything run finished on a small file in 15 seconds, but did not finish on the 3.2 MB file in 40 minutes.
The files:
ls(GPL-3.0-or-later), 153 KB.rsleigh was master at 13765bf06. Each time runs from process start to exit, so it includes loading the file. That is what one call per operation costs on these files.
ls, 153 KBls, every function: 372 of 373 functions had C, with 1 error. kuna took 5.3 s with 8 workers, and Ghidra took 15.3 s.These are first results, and more tests are coming. The APoseFix rows are one pass each and ran under load. "Under load" means the 1-minute load went over 4, and load is the average number of programs running or waiting for a core. This box has 24 threads. The CrashLogger rsleigh run stayed under 3.
The full tables, commands and test setup are in the Show and tell post.
🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊
@ShaneBreazeale commented on GitHub (Oct 16, 2026):
@CassieFox23, thanks for the timings and the C reads. They found real bugs. Fixes are in rsleigh v0.7.0 (
cargo install rsleigh --version 0.7.0 --locked, or the release archives).--allnow finishes. I profiled CrashLoggerSSE 1.25.0 (same sha256 as your run). There were three causes:0x18012e350, never finished. It is a double-to-decimal routine, and its conditions were printed in exponential time. With no per-function limit, it stalled the whole run. It now takes 0.12 s (ShaneBreazeale/rsleigh#30).CrashLogger.pdbthat ships next to the DLL. This is now done once per file (ShaneBreazeale/rsleigh#31).--jobs N(default: one per core) and--fn-timeout SECS(default 10 s with--all). JSON is printed as functions finish, and the output is the same for any--jobs(ShaneBreazeale/rsleigh#32).rsleigh FILE --all --jsonon CrashLogger now takes 41 s with 10 threads and 239 s with 1, on an Apple M4. That is not your Ryzen box, so it is not a head-to-head number. I have not rerun APoseFix.The one-line CrashLogger body (your Update 3). Your diagnosis was right on all four points. MSVC/clang-cl tables with image-base offsets, a zero-extended entry, and a signed-byte index with an entry at −1 are now recovered (ShaneBreazeale/rsleigh#29).
0x18006a500prints aswitchwithcase -1,2,3anddefault. Across the whole file, recovered jump tables went from 0 to 73.Silent partial output. Plain output and
--jsonnow report a body that stops at a branch rsleigh could not follow. The text gets a// WARNING:line, each JSON function gets astatus, and the exit code is 2 (ShaneBreazeale/rsleigh#28). The "possible scratch leak" messages were a check for one Python-extension packer that ran on every PE. It now runs only on files that import the Python C API.Compiling the C (your Update 1). I reran your check (
clang -fsyntax-only -std=gnu17 -w, extern stubs for callees and data labels) on 600 CrashLogger functions:The fixes behind that:
->on along: a variable used only through consistent fields gets a packed struct. Any other access prints as*(T *)(base + 0xN)(ShaneBreazeale/rsleigh#33).)inlscame from anS_ISDIRrewrite. Separately, conditions were printed without C precedence, sox & 0xf000 != 16384meantx & (0xf000 != 16384)(ShaneBreazeale/rsleigh#28, ShaneBreazeale/rsleigh#30).(*(void *)swi(0x29))(5)-style calls print as__fastfail(5)(ShaneBreazeale/rsleigh#35).std__exception__vftable(ShaneBreazeale/rsleigh#38).Wrong C, not just invalid C. Three of these changed meaning, not only syntax:
EAX = param_0->field_48;. Functions with a variable that is read but never set went from 2,772 to 2,138 of 3,889 (ShaneBreazeale/rsleigh#38)./GSfunctions returned the cookie check's result instead of their own value. CrashLogger0x18004e270printedreturn func_18013d100(lVar2 ^ RSP - 128); it now returnsparam_0(ShaneBreazeale/rsleigh#36).->field18matched the name for offset0x1(ShaneBreazeale/rsleigh#31).Still open:
lpDesktopon astd::string). This is now the most common remaining compile error.floatparameter.I'm working on the first and third next.
🤖 Generated with Claude Code (Opus 5.5)
@CassieFox23 commented on GitHub (Oct 18, 2026):
TL;DR: I reran my earlier rsleigh (Apache-2.0) checks on v0.7.0. Two fixes held on my files.
--allon CrashLoggerSSE 1.25.0 (MIT) now finishes in 24 seconds. The jump-table function prints aswitch. The C fix held in part: 1 of my 5 C files now compiles, up from 0, and I could not rerun the 10 MB file.Thanks, ShaneBreazeale, for the fixes and the detailed reply. I built the v0.7.0 tag, commit 158488f45 (ShaneBreazeale/rsleigh#39). Master has moved on by 10 commits since, and I did not test those.
Your three fixes, on my files
--allfinishes--all --json: stopped at the 40 minute limit, exit 124, no JSONok, 271partial. No function hit the per-function time limit.0x18006a500iVar1 = *(uint32_t*)(0x6a650 + DAT_180000000 + (char)param_1->field_48 * 4);switch (*(int8_t *)(param_1 + 0x48))withcase -1,case 2,case 3anddefaultls0x3e10)The C check used clang 22.1.8 and gcc 16.2.1 with
-std=gnu17 -fsyntax-only -w, on the same five functions as my earlier check. I wrote my own stubs for callees and data labels, so they may differ from yours. Some of the four failures may come from my stubs.What changed in the
lsfunction at0x3e10:)is gone. It now readsif ((*(int32_t *)((char *)param_1 + 0xac) & 0xf000) != 0x4000 /* !S_ISDIR */) {.iVar2is now set beforeif (iVar2 == 3).lVar2is still read without being set.param_0->field_a8on aconst char *is now*(int32_t *)((char *)param_0 + 0xa8).Still wrong in the CrashLogger function:
float fparam_0is still in the signature, andpuVar1->lpDesktop = 0;puts a Win32 field name on avoid *. You list that as still open. The--card --decompilecall on that function still exits 2 and sayspartial, now withdecode_failedat0x18006a64einstead ofunresolved_control_flowat0x18006a520.Old numbers next to new ones
Each cell is wall time, then peak memory of the process, in MiB. The old numbers come from three earlier commits, so I name each. The old posts said "MB" for the same field, which I believe is KiB divided by 1,024 (unverified for the 10-15 post).
maintruestubls0x5580sqlite3_freemaintruelssqlite3ls0x3e10ls--all,lsok, 372 with C text.--all, CrashLoggerWith one thread (
--jobs 1), CrashLoggerSSE--alltook 4 min 36 s, 72 MiB, exit 2 (load 7.8 at the start, so rough). The JSON was byte-identical to the 24-thread run, as the reply says. The single-thread run is the closest match to the earlier 40 minute run.Your Update 3 case and my earlier error-code checks also hold or improved:
--deadline-ms 1on0x42960still exits 1 witherror_codeexecution_limit.--xrefs sqlite3_freeon the Fedoralibsqlite3.so.3.51.2no longer panics. It finds 387 callers at 978 call sites, with exit 2. I do not know why it exits 2.--search sqlite3_freeon the same file no longer crashes with a stack overflow. It finds 387 matches, exit 2, but takes 63 s.Not run
--allrow.Commands
Build, from the extracted v0.7.0 tag. The generate step must run with the clone as the working folder.
Timed runs. Each was
/usr/bin/time -v timeout N rsleigh .... The--allruns were insidesystemd-run --user --scope -p MemoryMax=8G -p MemorySwapMax=0, withtimeout 1800.C check, for each output file after adding the stubs:
Test setup
mainwith-O1 -no-pie.lsandtrue(GPL-3.0-or-later), SQLite 3.51.2 (public domain), from Fedora packages. Same sha256 as my earlier posts.--jobs 1runs ran in the background during the small runs.🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊