Skip to content

Debugger.setInstrumentationBreakpoint is broken #31138

Description

@ulitink
  • Version: v14.0.0-pre, master branch
  • Platform: Linux
  • Subsystem: inspector

Newly added Debugger.setInstrumentationBreakpoint inspector API doesn't work for me. Changes were introduced for request #24687. The same API works fine in Chrome.

I've created a test #31137. Breakpoints for scripts with sourcemaps only don't work either. If I use the protocol incorrectly, please let me know which additional methods should be called.

Activity

  1. added
    inspectorIssues and PRs related to the V8 inspector protocol.
    on Dec 30, 2019
  2. addaleax commented on Dec 30, 2019

    @addaleax
    Member

    @nodejs/v8-inspector

  3. Soarex16 commented on Nov 13, 2023

    @Soarex16

    Any updates for this issue?

  4. Soarex16 commented on Jun 1, 2026

    @Soarex16

    Hi! I fixed the issue in V8 (commit, issue in V8) - turns out it doesn't work only with CJS modules.

    So when the dependency on V8 is updated this issue should be fixed.

    Why it happens

    Node's CJS loader compiles modules via v8::ScriptCompiler::CompileFunction - it passes the raw module text plus a parameter list - exports, require, module, __filename, __dirname (see GetCJSParameters).

    Compiler::GetWrappedFunction through Parser synthesizes an eval-style outer scope whose only statement is a return of the wrapped function literal.
    Conceptually, the AST V8 ends up parsing looks like this:

    // before
    console.log('hello from CJS module');
    // after
    return function (exports, require, module, __filename, __dirname) {
      console.log('hello from CJS module');
    };

    Two SFIs come out of that compilation:

    • Script (is_wrapped == true)
      • SFI#1 is_toplevel, bytecode = return <fn #2> (never called, but we set breakpoint there!)
      • SFI#2 is_wrapped, bytecode = console.log(...) (this one actually runs)

    GetWrappedFunction returns SFI#2 to Node, Node invokes it, hello from module is logged.

    And finally, when we send an instrumentation breakpoint request, Script::SetInstrumentationBreakpoint walks the SFIs and picks the first is_toplevel() one - SFI#1. But SFI#1 is the synthetic return <FUNCTION> wrapper that nobody ever calls.

  5. brynary commented on Aug 30, 2026

    @brynary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    inspectorIssues and PRs related to the V8 inspector protocol.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions