Description
- Version: v13.6.0
- Platform: Linux dragiyski-laptop 4.15.0-72-generic fs: fix fd leak on early readstream destroy #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
- Subsystem: inspector
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.