[GH-ISSUE #8311] [Bug] CLI decompile timeout describes a session that has already ended #6535

Closed
opened 2026-11-01 21:12:02 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @morluto on GitHub (Oct 31, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/8311

Originally assigned to: @kaoru0822-kitauji on GitHub.

Before submitting

  • I searched the open and closed issues and pull requests for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

CLI; native analysis or decompilation.

Observed behavior

A real rea decompile CLI call that reaches Ghidra's per-function deadline returns the useful provider_timeout and a CLI environment-variable recovery, but its headline says “the Ghidra session remains usable.” Its structured limit also describes an editable REA runtime setting applying to the next operation without a restart. A one-shot CLI invocation has finished and releases its provider session before the user can perform a next operation in it. The MCP runtime-setting and same-session advice is appropriate for a continuing MCP session, but is presented first in this CLI result.

Reproduction

With Ghidra 12.1.4, JDK 21 and a self-built arm64 Mach-O containing a deliberately slow 2,000-branch function, I ran once each:

  1. REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS=1 rea decompile <fixture> _slow_audit --provider ghidra --format json: exit 1, provider_timeout, retryable: true, message includes “the Ghidra session remains usable.” The details.limit identifies ghidra.decompile_timeout_seconds, scope: rea-runtime, applies_at: next_operation, rea_restart_required: false. The remediation also correctly says CLI or future processes can set REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS.
  2. With the same limit, rea function <fixture> _slow_audit --provider ghidra --format json exited 0 with pseudocode unavailable due to the deadline but nonempty assembly and basic blocks. This is a partial dossier, not a successful decompile.
  3. In a new process, raising the environment value to 60 and rerunning rea decompile returned pseudocode. The target SHA-256 was unchanged and it was never executed. The time needed by other functions or hosts is unknown.

Separately, real MCP controls in #8223 show that a provider deadline can preserve an open session and prior annotations, and its runtime setting can be raised there. This report is about the one-shot CLI presentation, not the timeout implementation or MCP's correct continued-session behavior.

Expected behavior

Distinguish the provider's per-request outcome from the lifetime of the calling adapter. In CLI output, lead with the environment variable and new invocation; do not imply the finished CLI command's ephemeral Program can accept another operation. Preserve the existing MCP-specific runtime update and same-session guidance, typed timeout and partial-dossier route. runDirectAnalysis documents that each CLI invocation is isolated and releases provider resources.

Impact and scope

The correct CLI recovery is present, so this is conflicting guidance rather than a total inability to recover. Only the stated macOS/Ghidra fixture and one call of each variant were exercised. No autonomous-agent behavior, cancellation, other providers, or frequency was measured.

REA version

b43c329df779708e43ae297f498a844e45d9c923; the relevant Ghidra and CLI source is unchanged at checked origin/main 23de10bb2849cdce8ddbe70504aa7cc57de75a98.

Runtime and platform

Node 24.22.1; macOS arm64; Ghidra 12.1.4; JDK 21.

Target and artifact context

Self-built Mach-O arm64 dylib; SHA-256 c4e954b46a27124a5e225d15d80089ce6661544635206dcc0cab189ebfc5af25; unchanged and not executed.

Interface

CLI.

Earliest failure stage

Transport or result projection.

Relevant output or evidence

The CLI output includes both the reusable-session sentence and For CLI or future REA processes, set REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS. The partial rea function result marks facet_availability.pseudocode.available: false and retains listing facts.

Typed outcome or recovery expected

A caller-appropriate timeout message and limit scope, keeping the original timeout detail and truthful MCP behavior.

Analysis or suspected cause

Source-derived: GhidraProviderClient constructs a shared provider error containing session-reuse guidance; runDirectAnalysis runs and releases one CLI session. The appropriate owning boundary for adapter-aware presentation needs design; do not fix by parsing arbitrary message text.

Additional context

Related: #5340 introduced the per-function deadline; #8223 concerns cancellation and lost live annotations; #8171 concerns verifier JDK setup. Last known good CLI wording: NOT_ENOUGH_INFO.

Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0.

Originally created by @morluto on GitHub (Oct 31, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8311 Originally assigned to: @kaoru0822-kitauji on GitHub. ### Before submitting - [x] I searched the open and closed issues and pull requests for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area CLI; native analysis or decompilation. ### Observed behavior A real `rea decompile` CLI call that reaches Ghidra's per-function deadline returns the useful `provider_timeout` and a CLI environment-variable recovery, but its headline says “the Ghidra session remains usable.” Its structured limit also describes an editable REA runtime setting applying to the next operation without a restart. A one-shot CLI invocation has finished and releases its provider session before the user can perform a next operation in it. The MCP runtime-setting and same-session advice is appropriate for a continuing MCP session, but is presented first in this CLI result. ### Reproduction With Ghidra 12.1.4, JDK 21 and a self-built arm64 Mach-O containing a deliberately slow 2,000-branch function, I ran once each: 1. `REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS=1 rea decompile <fixture> _slow_audit --provider ghidra --format json`: exit 1, `provider_timeout`, `retryable: true`, message includes “the Ghidra session remains usable.” The `details.limit` identifies `ghidra.decompile_timeout_seconds`, `scope: rea-runtime`, `applies_at: next_operation`, `rea_restart_required: false`. The remediation also correctly says CLI or future processes can set `REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS`. 2. With the same limit, `rea function <fixture> _slow_audit --provider ghidra --format json` exited 0 with pseudocode unavailable due to the deadline but nonempty assembly and basic blocks. This is a partial dossier, not a successful decompile. 3. In a new process, raising the environment value to 60 and rerunning `rea decompile` returned pseudocode. The target SHA-256 was unchanged and it was never executed. The time needed by other functions or hosts is unknown. Separately, real MCP controls in #8223 show that a provider deadline can preserve an open session and prior annotations, and its runtime setting can be raised there. This report is about the one-shot CLI presentation, not the timeout implementation or MCP's correct continued-session behavior. ### Expected behavior Distinguish the provider's per-request outcome from the lifetime of the calling adapter. In CLI output, lead with the environment variable and new invocation; do not imply the finished CLI command's ephemeral Program can accept another operation. Preserve the existing MCP-specific runtime update and same-session guidance, typed timeout and partial-dossier route. `runDirectAnalysis` documents that each CLI invocation is isolated and releases provider resources. ### Impact and scope The correct CLI recovery is present, so this is conflicting guidance rather than a total inability to recover. Only the stated macOS/Ghidra fixture and one call of each variant were exercised. No autonomous-agent behavior, cancellation, other providers, or frequency was measured. ### REA version `b43c329df779708e43ae297f498a844e45d9c923`; the relevant Ghidra and CLI source is unchanged at checked `origin/main` `23de10bb2849cdce8ddbe70504aa7cc57de75a98`. ### Runtime and platform Node 24.22.1; macOS arm64; Ghidra 12.1.4; JDK 21. ### Target and artifact context Self-built Mach-O arm64 dylib; SHA-256 `c4e954b46a27124a5e225d15d80089ce6661544635206dcc0cab189ebfc5af25`; unchanged and not executed. ### Interface CLI. ### Earliest failure stage Transport or result projection. ### Relevant output or evidence The CLI output includes both the reusable-session sentence and `For CLI or future REA processes, set REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS`. The partial `rea function` result marks `facet_availability.pseudocode.available: false` and retains listing facts. ### Typed outcome or recovery expected A caller-appropriate timeout message and limit scope, keeping the original timeout detail and truthful MCP behavior. ### Analysis or suspected cause Source-derived: [`GhidraProviderClient`](https://github.com/morluto/rea/blob/b43c329df779708e43ae297f498a844e45d9c923/src/ghidra/GhidraProviderClient.ts#L1137-L1156) constructs a shared provider error containing session-reuse guidance; [`runDirectAnalysis`](https://github.com/morluto/rea/blob/b43c329df779708e43ae297f498a844e45d9c923/src/application/DirectAnalysis.ts#L120-L146) runs and releases one CLI session. The appropriate owning boundary for adapter-aware presentation needs design; do not fix by parsing arbitrary message text. ### Additional context Related: #5340 introduced the per-function deadline; #8223 concerns cancellation and lost live annotations; #8171 concerns verifier JDK setup. Last known good CLI wording: NOT_ENOUGH_INFO. Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0.
bsakaguchi 2026-11-01 21:12:02 +00:00
  • closed this issue
  • added the
    bug
    triage
    labels
Author
Owner

@morluto commented on GitHub (Oct 31, 2026):

Partial dossier retained and inspected offline

A separate real CLI control used the same owned slow Mach-O and one-second Ghidra limit with rea function <fixture> _slow_audit --provider ghidra --detail summary --evidence_output <new bundle> --format json. The command exited 0 as a partial analysis: its summary marked pseudocode unavailable with the deadline reason, and assembly and CFG available. The source-owned fixture was unchanged and not executed.

Using the returned exact parent Evidence ID and that bundle, two later rea inspect-analysis-view CLI calls retrieved a pseudocode view reporting available: false with the same timeout reason and the first ten assembly instructions with a next-page offset, without reopening a provider. The bundle hash stayed unchanged. This checks one real partial-output and handoff path; the unavailable pseudocode is not an empty successful decompilation.

For context, this deliberately large 2,000-branch fixture's saved bundle was 22,752,356 bytes, while its serialized summary response was 9,257 bytes. Those are sizes for this fixture and representation, not token counts, latency or a general resource limit; the summary does not eliminate the cost of constructing and retaining the complete dossier. This positive path does not resolve the conflicting one-shot CLI session guidance reported above.

Cross-adapter control: a fresh stdio MCP server imported that CLI-created bundle with binary_session.open: false, then retrieved the same pseudocode-unavailable and first assembly-page views by retained ID. Both normalized results and view Evidence IDs matched the CLI views. The imported bundle's hash stayed unchanged. This is one partial dossier; it does not establish a general size limit or every CLI/MCP combination.

<!-- gh-comment-id:6544616582 --> @morluto commented on GitHub (Oct 31, 2026): ### Partial dossier retained and inspected offline A separate real CLI control used the same owned slow Mach-O and one-second Ghidra limit with `rea function <fixture> _slow_audit --provider ghidra --detail summary --evidence_output <new bundle> --format json`. The command exited 0 as a partial analysis: its summary marked pseudocode unavailable with the deadline reason, and assembly and CFG available. The source-owned fixture was unchanged and not executed. Using the returned exact parent Evidence ID and that bundle, two later `rea inspect-analysis-view` CLI calls retrieved a pseudocode view reporting `available: false` with the same timeout reason and the first ten assembly instructions with a next-page offset, without reopening a provider. The bundle hash stayed unchanged. This checks one real partial-output and handoff path; the unavailable pseudocode is not an empty successful decompilation. For context, this deliberately large 2,000-branch fixture's saved bundle was 22,752,356 bytes, while its serialized summary response was 9,257 bytes. Those are sizes for this fixture and representation, not token counts, latency or a general resource limit; the summary does not eliminate the cost of constructing and retaining the complete dossier. This positive path does not resolve the conflicting one-shot CLI session guidance reported above. Cross-adapter control: a fresh stdio MCP server imported that CLI-created bundle with `binary_session.open: false`, then retrieved the same pseudocode-unavailable and first assembly-page views by retained ID. Both normalized results **and** view Evidence IDs matched the CLI views. The imported bundle's hash stayed unchanged. This is one partial dossier; it does not establish a general size limit or every CLI/MCP combination.
Sign in to join this conversation.
No milestone
No project
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#6535
No description provided.