-
Notifications
You must be signed in to change notification settings - Fork 30.7k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Segfaults with dynamic imports and mocha #27492
Comments
I removed most of the external dependencies: only |
Debug backtrace (on
|
With the following diff, we get: https://gist.github.com/targos/7d9d1dc657a322519de758d8b29e9e21 diff --git a/src/module_wrap.cc b/src/module_wrap.cc
index a4e81dcc29..4ffb2534df 100644
--- a/src/module_wrap.cc
+++ b/src/module_wrap.cc
@@ -975,6 +975,7 @@ static MaybeLocal<Promise> ImportModuleDynamically(
ModuleWrap* wrap = ModuleWrap::GetFromID(env, id);
object = wrap->object();
} else if (type == ScriptType::kFunction) {
+ printf("find: %i\n", id);
object = env->id_to_function_map.find(id)->second.Get(iso);
} else {
UNREACHABLE();
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
index f8d43e062e..fdd3d41381 100644
--- a/src/node_contextify.cc
+++ b/src/node_contextify.cc
@@ -289,7 +289,9 @@ void ContextifyContext::WeakCallback(
void ContextifyContext::WeakCallbackCompileFn(
const WeakCallbackInfo<CompileFnEntry>& data) {
CompileFnEntry* entry = data.GetParameter();
+ printf("weakcallback %i\n", entry->id);
if (entry->env->compile_fn_entries.erase(entry) != 0) {
+ printf("erase %i\n", entry->id);
entry->env->id_to_function_map.erase(entry->id);
delete entry;
}
@@ -1110,6 +1112,7 @@ void ContextifyContext::CompileFunction(
return;
}
Local<Function> fn = maybe_fn.ToLocalChecked();
+ printf("emplace %i\n", id);
env->id_to_function_map.emplace(std::piecewise_construct,
std::make_tuple(id),
std::make_tuple(isolate, fn));
|
So, if I understand correctly, the issue is that the main script's ( It can be reproduced immediately after the first import with: diff --git a/build/test/test.esm.js b/build/test/test.esm.js
index ee16ed3..ce3c438 100644
--- a/build/test/test.esm.js
+++ b/build/test/test.esm.js
@@ -1,6 +1,7 @@
(async () => {
console.log("Before imports");
await import("./test/builtins/sint8.spec.mjs");
+ gc();
console.log("Imports: 1");
await import("./test/builtins/uint8.spec.mjs");
console.log("Imports: 2");
diff --git a/run.sh b/run.sh
index aff31ff..8fbaf07 100755
--- a/run.sh
+++ b/run.sh
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
set -ex
-node --experimental-modules --es-module-specifier-resolution=node node_modules/mocha/bin/_mocha build/test/test.esm.js --delay --async --no-config --no-package --no-opts --diff --extension js --reporter spec --slow 75 --timeout 2000 --ui bdd
+node --expose-gc --experimental-modules --es-module-specifier-resolution=node node_modules/mocha/bin/_mocha build/test/test.esm.js --delay --async --no-config --no-package --no-opts --diff --extension js --reporter spec --slow 75 --timeout 2000 --ui bdd |
thanks for looking into this targos. I've been planning a rewrite of module internals to fix a bunch of GC issues, I guess this is just the latest on the pile. |
I too experienced reproduceable segfaults with ESM imports after upgrading lately. I'm not familiar with the NodeJS-source but I managed to narrow it down to something between the versions v10.15.2 (works) and v10.15.3 (segfault). |
This only puts off the inevitable, but I found using this snippet in my mocha loader: (async () => {
const matches = globSync(join(__dirname, "**/*-test.mjs"));
await Promise.all(matches.map(x => import(pathToFileURL(resolve(x)).href)));
run();
})(); lets me get a tiny bit further :) Here's hoping this bug can be fixed as it affects both v10 LTS and v12! |
I was trying to repro this, but it just freezes on the second import line now. cc @targos 'use strict';
(async () => {
await import('./test1.mjs');
console.log('1');
gc();
console.log('gc');
await import('./test2.mjs');
console.log('2');
})(); |
GC behavior probably changed with V8 7.5 |
ok i can reproduce it after #27775 (although there seems to bug in 27775) |
I am testing the new ESM implementation on one of my projects. I am able to consistently get segfaults when using experimental modules and dynamic imports with mocha unit tests.
I extracted a reproducible example to demurgos/node-esm-sigsegv. I am working on reducing the example to be minimal.
The README.md has more details, here is a summary:
You can clone the repo, install the dependencies and run the following command:
The segfault occurs while evaluating the function in test.esm.js.
This function sequentially dynamically imports ESM spec files.
When importing a single file, the execution succeeds.
When importing 2 or 3 files, the execution segfaults 25% of the time.
When importing more files, the execution always segfaults.
I don't know the exact cause of the segfault yet. I am working on isolating it to a minimal example.
It is worth noting that Mocha injects global variables (which may interact badly with ES modules). It may also be a mocha bug, at the moment I am suspecting an ESM issue because it is a C++ crash (and not a JS exception).
The text was updated successfully, but these errors were encountered: