diff --git a/src/api/embed_helpers.cc b/src/api/embed_helpers.cc index 998d7507fc0eba..ff0f8d7f723447 100644 --- a/src/api/embed_helpers.cc +++ b/src/api/embed_helpers.cc @@ -53,6 +53,7 @@ Maybe SpinEventLoop(Environment* env) { if (env->is_stopping()) return Nothing(); env->set_trace_sync_io(false); + env->PrintInfoForSnapshotIfDebug(); env->VerifyNoStrongBaseObjects(); return EmitProcessExit(env); } diff --git a/src/env.cc b/src/env.cc index 0240572e49e7be..28a1c2fd3c3676 100644 --- a/src/env.cc +++ b/src/env.cc @@ -1232,6 +1232,25 @@ void Environment::RemoveUnmanagedFd(int fd) { } } +void Environment::PrintInfoForSnapshotIfDebug() { + if (enabled_debug_list()->enabled(DebugCategory::MKSNAPSHOT)) { + fprintf(stderr, "BaseObjects at the exit of the Environment:\n"); + PrintAllBaseObjects(); + fprintf(stderr, "\nNative modules without cache:\n"); + for (const auto& s : native_modules_without_cache) { + fprintf(stderr, "%s\n", s.c_str()); + } + fprintf(stderr, "\nNative modules with cache:\n"); + for (const auto& s : native_modules_with_cache) { + fprintf(stderr, "%s\n", s.c_str()); + } + fprintf(stderr, "\nStatic bindings (need to be registered):\n"); + for (const auto mod : internal_bindings) { + fprintf(stderr, "%s:%s\n", mod->nm_filename, mod->nm_modname); + } + } +} + void Environment::PrintAllBaseObjects() { size_t i = 0; std::cout << "BaseObjects\n"; diff --git a/src/env.h b/src/env.h index d1543f95e1aac6..6b8444f0bc578c 100644 --- a/src/env.h +++ b/src/env.h @@ -960,6 +960,7 @@ class Environment : public MemoryRetainer { void CreateProperties(); void DeserializeProperties(const EnvSerializeInfo* info); + void PrintInfoForSnapshotIfDebug(); void PrintAllBaseObjects(); void VerifyNoStrongBaseObjects(); void EnqueueDeserializeRequest(DeserializeRequestCallback cb, @@ -1123,6 +1124,7 @@ class Environment : public MemoryRetainer { // List of id's that have been destroyed and need the destroy() cb called. inline std::vector* destroy_async_id_list(); + std::set internal_bindings; std::set native_modules_with_cache; std::set native_modules_without_cache; // This is only filled during deserialization. We use a vector since diff --git a/src/node_binding.cc b/src/node_binding.cc index 6c7ab4b21eda9f..b5e42af79510b6 100644 --- a/src/node_binding.cc +++ b/src/node_binding.cc @@ -582,6 +582,7 @@ void GetInternalBinding(const FunctionCallbackInfo& args) { node_module* mod = FindModule(modlist_internal, *module_v, NM_F_INTERNAL); if (mod != nullptr) { exports = InitModule(env, mod, module); + env->internal_bindings.insert(mod); } else if (!strcmp(*module_v, "constants")) { exports = Object::New(env->isolate()); CHECK(