src: drain platform tasks before creating startup snapshot

Drain the loop and platform tasks before creating a snapshot. This is
necessary to ensure that the no roots are held by the the platform
tasks, which may reference objects associated with a context. For
example, a WeakRef may schedule an per-isolate platform task as a GC
root, and referencing an object in a context, causing an assertion in
the snapshot creator.

PR-URL: https://github.com/nodejs/node/pull/56403
Refs: https://github.com/nodejs/node/pull/56292
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
pull/56499/head
Chengzhong Wu 2025-01-07 11:03:55 +00:00 committed by GitHub
parent 062ae6f3cb
commit 52c644966d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 14 additions and 10 deletions

View File

@ -973,25 +973,29 @@ ExitCode BuildSnapshotWithoutCodeCache(
}
});
Context::Scope context_scope(setup->context());
Environment* env = setup->env();
// Run the custom main script for fully customized snapshots.
if (snapshot_type == SnapshotMetadata::Type::kFullyCustomized) {
Context::Scope context_scope(setup->context());
Environment* env = setup->env();
#if HAVE_INSPECTOR
env->InitializeInspector({});
#endif
if (LoadEnvironment(env, builder_script_content.value()).IsEmpty()) {
return ExitCode::kGenericUserError;
}
}
// FIXME(joyeecheung): right now running the loop in the snapshot
// builder might introduce inconsistencies in JS land that need to
// be synchronized again after snapshot restoration.
ExitCode exit_code =
SpinEventLoopInternal(env).FromMaybe(ExitCode::kGenericUserError);
if (exit_code != ExitCode::kNoFailure) {
return exit_code;
}
// Drain the loop and platform tasks before creating a snapshot. This is
// necessary to ensure that the no roots are held by the the platform
// tasks, which may reference objects associated with a context. For
// example, a WeakRef may schedule an per-isolate platform task as a GC
// root, and referencing an object in a context, causing an assertion in
// the snapshot creator.
ExitCode exit_code =
SpinEventLoopInternal(env).FromMaybe(ExitCode::kGenericUserError);
if (exit_code != ExitCode::kNoFailure) {
return exit_code;
}
}