| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 5202b84 commit 03e8d82
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -97,10 +97,9 @@ void InternalCallbackScope::Close() { | |||
| 97 | 97 | if (closed_) return; | |
| 98 | 98 | closed_ = true; | |
| 99 | 99 | ||
| 100 | - Isolate* isolate = env_->isolate(); | ||
| 101 | - auto idle = OnScopeLeave([&]() { isolate->SetIdle(true); }); | ||
| 100 | + // This function must ends up with either cleanup the | ||
| 101 | + // async id stack or pop the topmost one from it | ||
| 102 | 102 | ||
| 103 | - if (!env_->can_call_into_js()) return; | ||
| 104 | 103 | auto perform_stopping_check = [&]() { | |
| 105 | 104 | if (env_->is_stopping()) { | |
| 106 | 105 | MarkAsFailed(); | |
@@ -109,6 +108,11 @@ void InternalCallbackScope::Close() { | |||
| 109 | 108 | }; | |
| 110 | 109 | perform_stopping_check(); | |
| 111 | 110 | ||
| 111 | + if (env_->is_stopping()) return; | ||
| 112 | + | ||
| 113 | + Isolate* isolate = env_->isolate(); | ||
| 114 | + auto idle = OnScopeLeave([&]() { isolate->SetIdle(true); }); | ||
| 115 | + | ||
| 112 | 116 | if (!failed_ && async_context_.async_id != 0 && !skip_hooks_) { | |
| 113 | 117 | AsyncWrap::EmitAfter(env_, async_context_.async_id); | |
| 114 | 118 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -802,6 +802,7 @@ ThreadId AllocateEnvironmentThreadId() { | |||
| 802 | 802 | } | |
| 803 | 803 | ||
| 804 | 804 | void DefaultProcessExitHandler(Environment* env, int exit_code) { | |
| 805 | + env->set_stopping(true); | ||
| 805 | 806 | env->set_can_call_into_js(false); | |
| 806 | 807 | env->stop_sub_worker_contexts(); | |
| 807 | 808 | env->isolate()->DumpAndResetStats(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,32 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('../common'); | ||
| 3 | + | ||
| 4 | + // https://github.com/nodejs/node/issues/45421 | ||
| 5 | + // | ||
| 6 | + // Check that node will NOT call v8::Isolate::SetIdle() when exiting | ||
| 7 | + // due to an unhandled exception, otherwise the assertion(enabled in | ||
| 8 | + // debug build only) in the SetIdle(), which checks that the vm state | ||
| 9 | + // is either EXTERNAL or IDLE will fail. | ||
| 10 | + // | ||
| 11 | + // The root cause of this issue is that before PerIsolateMessageListener() | ||
| 12 | + // is invoked by v8, v8 preserves the JS vm state, although it should | ||
| 13 | + // switch to EXTERNEL. https://bugs.chromium.org/p/v8/issues/detail?id=13464 | ||
| 14 | + // | ||
| 15 | + // Therefore, this commit can be considered as an workaround of the v8 bug, | ||
| 16 | + // but we also find it not useful to call SetIdle() when terminating. | ||
| 17 | + | ||
| 18 | + if (process.argv[2] === 'child') { | ||
| 19 | + const { Worker } = require('worker_threads'); | ||
| 20 | + new Worker('', { eval: true }); | ||
| 21 | + throw new Error('xxx'); | ||
| 22 | + } else { | ||
| 23 | + const assert = require('assert'); | ||
| 24 | + const { spawnSync } = require('child_process'); | ||
| 25 | + const result = spawnSync(process.execPath, [__filename, 'child']); | ||
| 26 | + | ||
| 27 | + const stderr = result.stderr.toString().trim(); | ||
| 28 | + // Expect error message to be preserved | ||
| 29 | + assert.match(stderr, /xxx/); | ||
| 30 | + // Expect no crash | ||
| 31 | + assert(!common.nodeProcessAborted(result.status, result.signal), stderr); | ||
| 32 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments