fix: crash when destroying node env with pending promises (#33280)
* fix: crash when destroying node env with pending promises * chore: add spec
This commit is contained in:
parent
652680e801
commit
b2c5623a13
4 changed files with 64 additions and 9 deletions
|
@ -151,17 +151,22 @@ void ElectronRendererClient::WillReleaseScriptContext(
|
||||||
if (env == node_bindings_->uv_env())
|
if (env == node_bindings_->uv_env())
|
||||||
node_bindings_->set_uv_env(nullptr);
|
node_bindings_->set_uv_env(nullptr);
|
||||||
|
|
||||||
// Destroy the node environment. We only do this if node support has been
|
// Destroying the node environment will also run the uv loop,
|
||||||
// enabled for sub-frames to avoid a change-of-behavior / introduce crashes
|
// Node.js expects `kExplicit` microtasks policy and will run microtasks
|
||||||
// for existing users.
|
// checkpoints after every call into JavaScript. Since we use a different
|
||||||
// We also do this if we have disable electron site instance overrides to
|
// policy in the renderer - switch to `kExplicit` and then drop back to the
|
||||||
// avoid memory leaks
|
// previous policy value.
|
||||||
auto prefs = render_frame->GetBlinkPreferences();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
gin_helper::MicrotasksScope microtasks_scope(env->isolate());
|
auto old_policy = isolate->GetMicrotasksPolicy();
|
||||||
|
DCHECK_EQ(v8::MicrotasksScope::GetCurrentDepth(isolate), 0);
|
||||||
|
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
|
||||||
|
|
||||||
node::FreeEnvironment(env);
|
node::FreeEnvironment(env);
|
||||||
if (env == node_bindings_->uv_env())
|
if (env == node_bindings_->uv_env())
|
||||||
node::FreeIsolateData(node_bindings_->isolate_data());
|
node::FreeIsolateData(node_bindings_->isolate_data());
|
||||||
|
|
||||||
|
isolate->SetMicrotasksPolicy(old_policy);
|
||||||
|
|
||||||
// ElectronBindings is tracking node environments.
|
// ElectronBindings is tracking node environments.
|
||||||
electron_bindings_->EnvironmentDestroyed(env);
|
electron_bindings_->EnvironmentDestroyed(env);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,13 @@ WebWorkerObserver::WebWorkerObserver()
|
||||||
|
|
||||||
WebWorkerObserver::~WebWorkerObserver() {
|
WebWorkerObserver::~WebWorkerObserver() {
|
||||||
lazy_tls.Pointer()->Set(nullptr);
|
lazy_tls.Pointer()->Set(nullptr);
|
||||||
gin_helper::MicrotasksScope microtasks_scope(
|
// Destroying the node environment will also run the uv loop,
|
||||||
node_bindings_->uv_env()->isolate());
|
// Node.js expects `kExplicit` microtasks policy and will run microtasks
|
||||||
|
// checkpoints after every call into JavaScript. Since we use a different
|
||||||
|
// policy in the renderer - switch to `kExplicit`
|
||||||
|
v8::Isolate* isolate = node_bindings_->uv_env()->isolate();
|
||||||
|
DCHECK_EQ(v8::MicrotasksScope::GetCurrentDepth(isolate), 0);
|
||||||
|
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
|
||||||
node::FreeEnvironment(node_bindings_->uv_env());
|
node::FreeEnvironment(node_bindings_->uv_env());
|
||||||
node::FreeIsolateData(node_bindings_->isolate_data());
|
node::FreeIsolateData(node_bindings_->isolate_data());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
const fs = require('fs');
|
||||||
|
const { ipcRenderer } = require('electron');
|
||||||
|
|
||||||
|
async function readFile(path) {
|
||||||
|
await fs.promises.readFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcRenderer.on('reload', (_, path) => {
|
||||||
|
readFile(path);
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,28 @@
|
||||||
|
const { app, BrowserWindow, ipcMain } = require('electron');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
let reloadCount = 0;
|
||||||
|
const win = new BrowserWindow({
|
||||||
|
show: false,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
win.loadFile('index.html');
|
||||||
|
|
||||||
|
win.webContents.on('render-process-gone', () => {
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
win.webContents.on('did-finish-load', () => {
|
||||||
|
if (reloadCount > 2) {
|
||||||
|
setImmediate(() => app.quit());
|
||||||
|
} else {
|
||||||
|
reloadCount += 1;
|
||||||
|
win.webContents.send('reload', path.join(__dirname, '..', '..', 'cat.pdf'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue