Skip to content

Fix call stack display for recursive function calls#203

Merged
gnidan merged 1 commit intocall-returnfrom
ui-fix-recursive-callstack
Apr 2, 2026
Merged

Fix call stack display for recursive function calls#203
gnidan merged 1 commit intocall-returnfrom
ui-fix-recursive-callstack

Conversation

@gnidan
Copy link
Copy Markdown
Member

@gnidan gnidan commented Apr 2, 2026

Summary

  • Fix call stack dedup logic that collapsed recursive calls into a single frame
  • The dedup now checks stepIndex === i - 1 to distinguish compiler-emitted duplicate invoke contexts (caller JUMP + callee JUMPDEST on consecutive steps) from genuine recursive calls (same function name but steps far apart)
  • Fixed in both programs-react/utils/mockTrace.ts and web/TraceDrawer.tsx

The call stack dedup logic compared only function name and
call type, causing recursive calls (e.g. count -> count) to
be collapsed into a single frame. Now also checks whether the
previous frame was pushed on the immediately preceding step,
which distinguishes the compiler's duplicate invoke contexts
(caller JUMP + callee JUMPDEST on consecutive steps) from
genuine recursive calls (same name but steps far apart).

Fixed in both programs-react buildCallStack and web
TraceDrawer's duplicated call stack logic.
@gnidan gnidan force-pushed the ui-fix-recursive-callstack branch from caeef59 to 59dd341 Compare April 2, 2026 09:22
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-04-02 09:38 UTC

Copy link
Copy Markdown
Member Author

@gnidan gnidan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dedup logic looks correct. Confirmed from the compiler side:

  • bugc emits invoke context on the caller JUMP (terminator.ts:271) and the callee entry JUMPDEST (function.ts:76). These are always consecutive EVM trace steps since JUMP lands directly on JUMPDEST.

  • The stepIndex === i - 1 condition correctly distinguishes the JUMP→JUMPDEST duplicate (consecutive, same identifier) from recursive calls (non-consecutive, same identifier). No edge cases I can see — mutual recursion uses different identifiers, and self-recursion always has many steps between the outer call's JUMPDEST and the inner call's JUMP.

@gnidan gnidan merged commit 322e55d into call-return Apr 2, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant