Skip to content

fix: keep hot-reload-patched callers visible in pause-point caller frames - #2277

Merged
hatayama merged 2 commits into
v3-betafrom
fix/pause-point-hot-reload-caller-frames
Aug 20, 2026
Merged

hatayama merged 2 commits into
v3-betafrom
fix/pause-point-hot-reload-caller-frames

Conversation

@hatayama

@hatayama hatayama commented Aug 20, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Pause-point CallerFrames now keep hot-reload-patched callers visible, reported as method-only frames under the original Type.Method name.
  • A fully hot-reloaded call chain no longer collapses to an empty [].

User Impact

  • Before: a hot-reloaded caller was dropped because its Harmony body looks like MonoMod infrastructure. One patched caller left only the compiled frames above it; patching every method in the chain produced [].
  • After: those callers appear as Method only (File and Line omitted, because a dynamic method carries no debug symbols). Compiled callers still include File/Line.

Changes

  • Resolve Harmony patch bodies (MonoMod.Utils.DynamicMethodDefinition + _Patch{N} name) to the original Type.Method before the infrastructure prefix skip.
  • After that resolution, patched uloop-internal and BCL callers stay hidden, matching their compiled counterparts.
  • Document the method-only patched-body shape, and note that a line that runs every frame fills capped trace history immediately.

Verification

  • dist/darwin-arm64/uloop compile: ErrorCount 0
  • PausePointCallerFrameSelectorTests: 39 passed (6 new cases covering _Patch1, _Patch12, no-suffix DMD, _PatchX, patched uloop-internal skip, and the all-patched chain)
  • PausePoint EditMode filter: 420 passed
  • scripts/sync-tool-docs.sh --check: catalog matches skill parameter tables

Live repro with the dist binary (temporary probe, not in this PR):

Dump 2 — nearest caller hot-reloaded, Update still compiled:

[
  { "Method": "CallerFrameProbe.ShallowCaller" },
  { "Method": "CallerFrameProbe.Update", "File": "Assets/CallerFrameProbe.cs", "Line": 15 }
]

Dump 3 — both callers hot-reloaded (previously []):

[
  { "Method": "CallerFrameProbe.ShallowCaller" },
  { "Method": "CallerFrameProbe.Update" }
]

Review in cubic

…ames

Harmony patch bodies appear as MonoMod.Utils.DynamicMethodDefinition
with a _PatchN name, so the MonoMod. prefix skip dropped every
hot-reloaded caller. Resolve those frames to the original Type.Method
before applying the infrastructure skip.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 20, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 825f6626-a14d-4ff1-9888-5c18d4eb73f6

📥 Commits

Reviewing files that changed from the base of the PR and between 977d0f8 and d94cfaa.

📒 Files selected for processing (5)
  • .agents/skills/uloop-pause-point/references/captured-variables.md
  • .claude/skills/uloop-pause-point/references/captured-variables.md
  • Assets/Tests/Editor/PausePointCallerFrameSelectorTests.cs
  • Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/references/captured-variables.md
  • Packages/src/Editor/FirstPartyTools/PausePoint/SourcePausePointCallerFrameSelector.cs

📝 Walkthrough

Walkthrough

The pause-point caller selector now recognizes Harmony dynamic patch methods, restores their original Type.Method names, omits unavailable source metadata, and filters infrastructure frames. Tests cover valid and invalid patch names, internal callers, async state machines, and patched call stacks. Documentation reflects the behavior.

Changes

Harmony caller-frame reporting

Layer / File(s) Summary
Dynamic frame resolution
Packages/src/Editor/FirstPartyTools/PausePoint/SourcePausePointConstants.cs, Packages/src/Editor/FirstPartyTools/PausePoint/SourcePausePointCallerFrameSelector.cs
The selector identifies Harmony dynamic methods, removes numeric _PatchN suffixes, filters infrastructure methods, demangles async state-machine names, and reports logical method names without file or line data.
Dynamic frame validation
Assets/Tests/Editor/PausePointCallerFrameSelectorTests.cs
Tests cover single- and multi-digit suffixes, invalid names, internal callers, async state machines, and stacks containing multiple Harmony-patched frames.
Pause-point documentation
.agents/skills/uloop-pause-point/..., .claude/skills/uloop-pause-point/..., Packages/src/Editor/CliOnlyTools~/PausePoint/...
Documentation describes method-only reporting for hot-reload-patched callers and recommends conditional trace targets to avoid filling capped history.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CallerStack
  participant SourcePausePointCallerFrameSelector
  participant FormatMethodDisplay
  CallerStack->>SourcePausePointCallerFrameSelector: Supply Harmony dynamic frames
  SourcePausePointCallerFrameSelector->>SourcePausePointCallerFrameSelector: Validate and strip _PatchN suffix
  SourcePausePointCallerFrameSelector->>FormatMethodDisplay: Format async state-machine method
  FormatMethodDisplay-->>SourcePausePointCallerFrameSelector: Return logical Type.Method
  SourcePausePointCallerFrameSelector-->>CallerStack: Return method-only caller frame
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: preserving hot-reload-patched callers in pause-point caller frames.
Description check ✅ Passed The description directly explains the caller-frame behavior, implementation changes, user impact, tests, and verification results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pause-point-hot-reload-caller-frames

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

A patched async body surfaces as a state-machine MoveNext_PatchN name;
route it through the same demangling as compiled frames so the payload
keeps the logical method name. Align the skip-prefix bullet with that
Harmony exception.

Co-authored-by: Cursor <cursoragent@cursor.com>
@hatayama
hatayama merged commit a9dd11b into v3-beta Aug 20, 2026
10 checks passed
@hatayama
hatayama deleted the fix/pause-point-hot-reload-caller-frames branch August 20, 2026 01:15
@github-actions github-actions Bot mentioned this pull request Aug 19, 2026
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