Skip to content

Commit 4662ab9

Browse files
authored
fix: crash with --inspect-brk when running under ELECTRON_RUN_AS_NODE (electron#20098)
* fix: ensure that the node env is not bootstrapped before running inspector * fix: ensure we wait for the inspect to disconnect This re-orders our node clean up so that we free the environment before the task runner is cleaned up as node uses the task runner during clean up. It also calls WaitForDisconnect() to ensure that inspector agents are notified that the context is going down. * chore: update spec to catch SIGABRT
1 parent e070bd7 commit 4662ab9

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

atom/app/node_main.cc

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ int NodeMain(int argc, char* argv[]) {
4747
feature_list->InitializeFromCommandLine("", "");
4848
base::FeatureList::SetInstance(std::move(feature_list));
4949

50-
gin::V8Initializer::LoadV8Snapshot(
51-
gin::V8Initializer::V8SnapshotFileType::kWithAdditionalContext);
52-
gin::V8Initializer::LoadV8Natives();
53-
54-
// V8 requires a task scheduler apparently
55-
base::ThreadPoolInstance::CreateAndStartWithDefaultParams("Electron");
56-
57-
// Initialize gin::IsolateHolder.
58-
JavascriptEnvironment gin_env(loop);
5950
#if defined(_WIN64)
6051
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
6152
#endif
@@ -67,14 +58,26 @@ int NodeMain(int argc, char* argv[]) {
6758
const char** exec_argv;
6859
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
6960

61+
gin::V8Initializer::LoadV8Snapshot(
62+
gin::V8Initializer::V8SnapshotFileType::kWithAdditionalContext);
63+
gin::V8Initializer::LoadV8Natives();
64+
65+
// V8 requires a task scheduler apparently
66+
base::ThreadPoolInstance::CreateAndStartWithDefaultParams("Electron");
67+
68+
// Initialize gin::IsolateHolder.
69+
JavascriptEnvironment gin_env(loop);
70+
7071
node::Environment* env = node::CreateEnvironment(
7172
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform()),
72-
gin_env.context(), argc, argv, exec_argc, exec_argv);
73+
gin_env.context(), argc, argv, exec_argc, exec_argv, false);
7374

7475
// Enable support for v8 inspector.
7576
NodeDebugger node_debugger(env);
7677
node_debugger.Start();
7778

79+
node::BootstrapEnvironment(env);
80+
7881
mate::Dictionary process(gin_env.isolate(), env->process_object());
7982
#if defined(OS_WIN)
8083
process.SetMethod("log", &ElectronBindings::Log);
@@ -110,12 +113,15 @@ int NodeMain(int argc, char* argv[]) {
110113

111114
node_debugger.Stop();
112115
exit_code = node::EmitExit(env);
116+
env->set_can_call_into_js(false);
113117
node::RunAtExit(env);
114-
gin_env.platform()->DrainTasks(env->isolate());
115-
gin_env.platform()->CancelPendingDelayedTasks(env->isolate());
116-
gin_env.platform()->UnregisterIsolate(env->isolate());
117118

119+
v8::Isolate* isolate = env->isolate();
118120
node::FreeEnvironment(env);
121+
122+
gin_env.platform()->DrainTasks(isolate);
123+
gin_env.platform()->CancelPendingDelayedTasks(isolate);
124+
gin_env.platform()->UnregisterIsolate(isolate);
119125
}
120126

121127
// According to "src/gin/shell/gin_main.cc":

atom/browser/node_debugger.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ void NodeDebugger::Start() {
6060

6161
void NodeDebugger::Stop() {
6262
auto* inspector = env_->inspector_agent();
63-
if (inspector && inspector->IsListening())
63+
if (inspector && inspector->IsListening()) {
64+
inspector->WaitForDisconnect();
6465
inspector->Stop();
66+
}
6567
}
6668

6769
} // namespace atom

spec/node-spec.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,13 +311,20 @@ describe('node feature', () => {
311311
output += data
312312
if (output.trim().startsWith('Debugger listening on ws://')) {
313313
cleanup()
314-
done()
314+
child.kill('SIGTERM')
315315
}
316316
}
317317
function outDataHandler (data) {
318318
cleanup()
319319
done(new Error(`Unexpected output: ${data.toString()}`))
320320
}
321+
child.on('close', (code, signal) => {
322+
if (signal !== 'SIGTERM') {
323+
done(new Error(`Unexpected termination with code: ${code} and signal: ${signal}`))
324+
} else {
325+
done()
326+
}
327+
})
321328
child.stderr.on('data', errorDataListener)
322329
child.stdout.on('data', outDataHandler)
323330
})
@@ -390,6 +397,7 @@ describe('node feature', () => {
390397
const connection = new WebSocket(socketMatch[0])
391398
connection.onopen = () => {
392399
child.send('plz-quit')
400+
connection.close()
393401
done()
394402
}
395403
}

0 commit comments

Comments
 (0)