feat(decompiler): cooperative analysis budget tracker (#35-3a)#231
Merged
Conversation
Rec 35 (bounded decompilation), next slice after the #35-2 request schema. Adds DecompileBudgetTracker (cpp/budget.hh): a dependency-free, header-only, single-thread tracker the analysis loop will consult at each yield point (pass entry/exit, every N iterations). It tracks soft/hard wall-clock, accumulated pcode-ops, and per-pass fixed-point iterations against the five caps from DECOMPILER_BUDGETS.md (defaults mirror the v1 request schema). It never interrupts: when a cap is reached it records which BudgetExhaustion class tripped, pinned to the pass that first ran out of budget, leaving the caller to checkpoint and return a partial result. Async cancellation in C++ analysis is undefined behaviour we deliberately do not take on. The millisecond clock source is injectable, so the wall-clock paths are unit-tested deterministically without sleeping (unittests/testbudget.cc, 9 cases: within-budget, soft/hard wall-clock with hard outranking soft, pcode-op cap, per-pass iteration cap, per-pass reset, sticky diagnostic pass, reset(), and literal zero-cap semantics). Inert as of this PR, mirroring how the #34-4 codec landed before being wired: caps are taken as plain values rather than the FlatBuffers DecompileBudgetV1, so the mechanism is decoupled from the IPC schema, and no production pass consults it yet. Wiring the yield-point checks into flow_analysis and data_flow is the behaviour-changing follow-up (#35-3b). Both new files carry the GHIDRA license header, so the :Decompiler:ip audit resolves them without a certification.manifest entry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Rec 31 cppRaiiAudit gate has a completeness check: every C++ file under src/decompile/cpp must be listed in either PROTECTED_FILES or EXCLUDED_FILES. The new budget.hh (#35-3a) was in neither, so the `audits` job's :cppRaiiAudit step failed CI with "1 ungated decompiler C++ file(s)". budget.hh has zero raw `new` sites (it is entirely value- and std-typed), so it lands in PROTECTED_FILES with no line-range exclusions ([]), the same bucket as the other already-clean headers. This gate is not run by scripts/local-precheck.sh (C++ build/test only), which is why the local prechecks were green; running `gradle cppRaiiAudit` locally now reports 229 protected file(s) clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Closes #230.
Next slice of Rec 35 (bounded decompilation) after the
#35-2request schema. AddsDecompileBudgetTracker(cpp/budget.hh): a dependency-free, header-only, single-thread tracker the analysis loop will consult at each yield point.What it does
DECOMPILER_BUDGETS.md(defaults mirror the v1 request schema).BudgetExhaustionclass pinned to the pass that first ran out, leaving the caller to checkpoint and return a partial result. Async cancel in C++ analysis is UB we deliberately avoid.Scope
Inert, mirroring how the
#34-4codec landed before being wired: caps are plain values (not the FlatBuffersDecompileBudgetV1), so the mechanism is decoupled from the IPC schema and no production pass consults it yet. Wiring the checks intoflow_analysis/data_flowis the behaviour-changing follow-up (#35-3b).Test plan
decomp_test_dbg unittests— 314/314 incl. 9 newbudget_*cases (within-budget, soft/hard wall-clock with hard outranking soft, pcode-op cap, per-pass iteration cap, per-pass reset, sticky diagnostic pass,reset(), literal zero-cap).ghidra_dbgbuilds; sleigh compile.:Decompiler:ip— both new files resolve from their license header, no manifest entry needed.Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/