Skip to content

Inspector crash on "step into" async function #31419

Closed
@Dragiyski

Description

@Dragiyski

If a step into command is invoked on a method that is async function of an prototype, with closure scopes, the node crashes. Here is hypothetical code:

// module.js
module.exports = function someClosure() {
  'use strict';

  const path = require('path');
  // ... other const values defined in this closure

  function Class() {
  }

  Class.prototype = Object.create(Object.prototype, {
    // Property definitions:
    method: {
      // Note: this occurred with non-configurable, non-writable function on the prototype
      enumerable: true,
      value: async function() { /* some code returning promise */ }
    }
  });
  return Class;
};
// index.js
const Class = require('./module')();
const instance = new Class();

// (1)Breakpoint on the next line
instance.method(/* ... some parameters ... */).then(/* ... */);

When a breakpoint is set on the method call and "step into" command is issued, the inspector crashes. If no breakpoint is set on line (1), but a breakpoint is set within the method, inspector runs normally. Note that the crush occurs when "step into" command is issued. Breaking on the line of the call is not a problem. All function scopes and closures can be examined without causing a crash.

Running with the same version of nodejs, but with a debug build from source, the following output is obtained:

Debugger listening on ws://127.0.0.1:9229/a2d8d490-5a7a-429e-8f4f-dbf64005d986
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.


#
# Fatal error in ../deps/v8/src/debug/debug-scopes.cc, line 132
# Debug check failed: (closure_scope_) != nullptr.
#
#
#
#FailureMessage Object: 0x7fffc820dc00
 1: 0x55ab92ec75a9 node::DumpBacktrace(_IO_FILE*) [/home/dragiyski/opt/node-v13.6.0/bin/node]
 2: 0x55ab9303c3cb  [/home/dragiyski/opt/node-v13.6.0/bin/node]
 3: 0x55ab9303c3eb  [/home/dragiyski/opt/node-v13.6.0/bin/node]
 4: 0x55ab9491a396 V8_Fatal(char const*, int, char const*, ...) [/home/dragiyski/opt/node-v13.6.0/bin/node]
 5: 0x55ab9491a3c5  [/home/dragiyski/opt/node-v13.6.0/bin/node]
 6: 0x55ab933bfd19 v8::internal::ScopeIterator::TryParseAndRetrieveScopes(v8::internal::ScopeIterator::Option) [/home/dragiyski/opt/node-v13.6.0/bin/node]
 7: 0x55ab933bdaf1 v8::internal::DebugScopeIterator::DebugScopeIterator(v8::internal::Isolate*, v8::internal::FrameInspector*) [/home/dragiyski/opt/node-v13.6.0/bin/node]
 8: 0x55ab933c96df v8::internal::DebugStackTraceIterator::GetScopeIterator() const [/home/dragiyski/opt/node-v13.6.0/bin/node]
 9: 0x55ab93c3d128 v8_inspector::V8DebuggerAgentImpl::currentCallFrames(std::unique_ptr<std::vector<std::unique_ptr<v8_inspector::protocol::Debugger::CallFrame, std::default_delete<v8_inspector::protocol::Debugger::CallFrame> >, std::allocator<std::unique_ptr<v8_inspector::protocol::Debugger::CallFrame, std::default_delete<v8_inspector::protocol::Debugger::CallFrame> > > >, std::default_delete<std::vector<std::unique_ptr<v8_inspector::protocol::Debugger::CallFrame, std::default_delete<v8_inspector::protocol::Debugger::CallFrame> >, std::allocator<std::unique_ptr<v8_inspector::protocol::Debugger::CallFrame, std::default_delete<v8_inspector::protocol::Debugger::CallFrame> > > > > >*) [/home/dragiyski/opt/node-v13.6.0/bin/node]
10: 0x55ab93c44956 v8_inspector::V8DebuggerAgentImpl::didPause(int, v8::Local<v8::Value>, std::vector<int, std::allocator<int> > const&, v8::debug::ExceptionType, bool, bool, bool) [/home/dragiyski/opt/node-v13.6.0/bin/node]
11: 0x55ab93c2a11a  [/home/dragiyski/opt/node-v13.6.0/bin/node]
12: 0x55ab93c5104c v8_inspector::V8InspectorImpl::forEachSession(int, std::function<void (v8_inspector::V8InspectorSessionImpl*)> const&) [/home/dragiyski/opt/node-v13.6.0/bin/node]
13: 0x55ab93c31b57 v8_inspector::V8Debugger::BreakProgramRequested(v8::Local<v8::Context>, std::vector<int, std::allocator<int> > const&) [/home/dragiyski/opt/node-v13.6.0/bin/node]
14: 0x55ab933db9eb v8::internal::Debug::OnDebugBreak(v8::internal::Handle<v8::internal::FixedArray>) [/home/dragiyski/opt/node-v13.6.0/bin/node]
15: 0x55ab933dbdb4 v8::internal::Debug::Break(v8::internal::JavaScriptFrame*, v8::internal::Handle<v8::internal::JSFunction>) [/home/dragiyski/opt/node-v13.6.0/bin/node]
16: 0x55ab939bae7a  [/home/dragiyski/opt/node-v13.6.0/bin/node]
17: 0x55ab939bb42b v8::internal::Runtime_DebugBreakOnBytecode(int, unsigned long*, v8::internal::Isolate*) [/home/dragiyski/opt/node-v13.6.0/bin/node]
18: 0x55ab93ff3a40  [/home/dragiyski/opt/node-v13.6.0/bin/node]
Illegal instruction (core dumped)

Here is source information extracted for the most relevant frames:

#3: ../deps/v8/src/debug/debug-scopes.cc:132
#4: ../deps/v8/src/debug/debug-scopes.cc:107
#5: ../deps/v8/src/debug/debug-scopes.cc:260

P.S. The bug occurs in the release version v13.6.0, as downloaded by nvm or even when using prebuilt linux-x64 node from NodeJS downloads. The debug output here is shown from debug build from source, but without non-optimized debug V8 (due to errors in GCC build of slow checks). Thus currently bt does not provide source information, while frame provides a source location, but no source files. Therefore, I cannot show better trace than this.

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