Skip to content

fix: enable interruption of V8 execution on Debugger.pause command#378

Open
edusperoni wants to merge 1 commit into
mainfrom
fix/pause-on-debugger-message
Open

fix: enable interruption of V8 execution on Debugger.pause command#378
edusperoni wants to merge 1 commit into
mainfrom
fix/pause-on-debugger-message

Conversation

@edusperoni
Copy link
Copy Markdown
Collaborator

@edusperoni edusperoni commented May 28, 2026

Summary by CodeRabbit

  • Bug Fixes
    • Improved JavaScript pause functionality in the debugger to work reliably when called from DevTools. Pause commands now interrupt script execution consistently, regardless of main thread workload or application state. This enhancement provides developers with a more responsive and predictable debugging experience across all usage scenarios.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

📝 Walkthrough

Walkthrough

This PR adds interrupt-based pause handling to the NativeScript V8 inspector client. When a Debugger.pause message arrives from DevTools, the code detects it and requests a V8 interrupt, scheduling the pause on the next statement execution rather than blocking immediately.

Changes

V8 Debugger pause interrupt handling

Layer / File(s) Summary
V8 debugger pause interrupt handling
NativeScript/inspector/JsV8InspectorClient.mm
Detects Debugger.pause protocol messages, parses JSON, and calls isolate_->RequestInterrupt with a callback that schedules a pause via session_, enabling pause during active JS execution.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A pause in the flow, 🐰
When debuggers call their song,
V8 stops to listen,
Brief and bright, not long.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: enabling V8 execution interruption in response to the Debugger.pause DevTools command.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@NativeScript/inspector/JsV8InspectorClient.mm`:
- Around line 131-141: The RequestInterrupt path for "Debugger.pause" should be
skipped when the inspector is already in a paused nested loop; wrap the existing
parsed-check and isolate_->RequestInterrupt call in a guard that only runs when
runningNestedLoops_ is false (i.e., if (!runningNestedLoops_) { ... }), so that
runMessageLoopOnPause() (which sets runningNestedLoops_ = true) continues to
handle pause messages via session_->schedulePauseOnNextStatement rather than
queuing an interrupt that re-pauses immediately; update the branch in
JsV8InspectorClient around the RequestInterrupt lambda to check
runningNestedLoops_ before calling isolate_->RequestInterrupt.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c306d087-23a0-4ae6-b87a-92dfe7f5b5b1

📥 Commits

Reviewing files that changed from the base of the PR and between ecd3598 and 7e6c842.

📒 Files selected for processing (1)
  • NativeScript/inspector/JsV8InspectorClient.mm

Comment on lines +131 to +141
// Debugger.pause needs to interrupt V8 even if the main thread is busy
// executing JS. RequestInterrupt fires at the next safe bytecode boundary.
auto parsed = json::parse(message, nullptr, false);
if (!parsed.is_discarded() && parsed.contains("method") && parsed["method"] == "Debugger.pause") {
isolate_->RequestInterrupt(
[](Isolate* isolate, void* data) {
auto client = static_cast<JsV8InspectorClient*>(data);
client->session_->schedulePauseOnNextStatement({}, {});
},
this);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Skip the interrupt path when the inspector is already paused.

runMessageLoopOnPause() already pumps frontend messages with runningNestedLoops_ = true. In that state no JS is executing, so this RequestInterrupt stays pending until after resume and can cause an unexpected immediate re-pause on the next statement. Gate the new branch on !runningNestedLoops_ and let the paused message loop handle Debugger.pause normally.

Suggested guard
   auto parsed = json::parse(message, nullptr, false);
-  if (!parsed.is_discarded() && parsed.contains("method") && parsed["method"] == "Debugger.pause") {
+  bool shouldInterrupt = false;
+  dispatch_sync(this->messageLoopQueue_, ^{
+    shouldInterrupt = !runningNestedLoops_;
+  });
+  if (shouldInterrupt && !parsed.is_discarded() && parsed.contains("method") &&
+      parsed["method"] == "Debugger.pause") {
     isolate_->RequestInterrupt(
         [](Isolate* isolate, void* data) {
           auto client = static_cast<JsV8InspectorClient*>(data);
           client->session_->schedulePauseOnNextStatement({}, {});
         },
         this);
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/inspector/JsV8InspectorClient.mm` around lines 131 - 141, The
RequestInterrupt path for "Debugger.pause" should be skipped when the inspector
is already in a paused nested loop; wrap the existing parsed-check and
isolate_->RequestInterrupt call in a guard that only runs when
runningNestedLoops_ is false (i.e., if (!runningNestedLoops_) { ... }), so that
runMessageLoopOnPause() (which sets runningNestedLoops_ = true) continues to
handle pause messages via session_->schedulePauseOnNextStatement rather than
queuing an interrupt that re-pauses immediately; update the branch in
JsV8InspectorClient around the RequestInterrupt lambda to check
runningNestedLoops_ before calling isolate_->RequestInterrupt.

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.

2 participants