Skip to content

Commit d153832

Browse files
bnoordhuiscodebytere
authored andcommitted
wasi,worker: handle termination exception
Be careful when emitting the 'beforeExit' event. It's not allowed to call into the runtime when a termination exception is pending. Fixes: #33377 PR-URL: #33386 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent d1e1dbf commit d153832

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

src/api/hooks.cc

+8-5
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,14 @@ void EmitBeforeExit(Environment* env) {
3737

3838
HandleScope handle_scope(env->isolate());
3939
Context::Scope context_scope(env->context());
40-
Local<Value> exit_code = env->process_object()
41-
->Get(env->context(), env->exit_code_string())
42-
.ToLocalChecked()
43-
->ToInteger(env->context())
44-
.ToLocalChecked();
40+
41+
Local<Value> exit_code_v;
42+
if (!env->process_object()->Get(env->context(), env->exit_code_string())
43+
.ToLocal(&exit_code_v)) return;
44+
45+
Local<Integer> exit_code;
46+
if (!exit_code_v->ToInteger(env->context()).ToLocal(&exit_code)) return;
47+
4548
ProcessEmit(env, "beforeExit", exit_code).ToLocalChecked();
4649
}
4750

src/node_process_events.cc

+6-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@ MaybeLocal<Value> ProcessEmit(Environment* env,
2424
const char* event,
2525
Local<Value> message) {
2626
// Send message to enable debug in cluster workers
27-
Local<Object> process = env->process_object();
2827
Isolate* isolate = env->isolate();
29-
Local<Value> argv[] = {OneByteString(isolate, event), message};
3028

29+
Local<String> event_string;
30+
if (!String::NewFromOneByte(isolate, reinterpret_cast<const uint8_t*>(event))
31+
.ToLocal(&event_string)) return MaybeLocal<Value>();
32+
33+
Local<Object> process = env->process_object();
34+
Local<Value> argv[] = {event_string, message};
3135
return MakeCallback(isolate, process, "emit", arraysize(argv), argv, {0, 0});
3236
}
3337

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Flags: --experimental-wasi-unstable-preview1
2+
'use strict';
3+
4+
const common = require('../common');
5+
const assert = require('assert');
6+
const { WASI } = require('wasi');
7+
const { Worker, parentPort } = require('worker_threads');
8+
9+
// void _start(void) { for (;;); }
10+
const bytecode = new Uint8Array([
11+
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60,
12+
0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01,
13+
0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41,
14+
0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f,
15+
0x72, 0x79, 0x02, 0x00, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00,
16+
0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x03, 0x40, 0x0c, 0x00, 0x0b, 0x0b,
17+
0x00, 0x10, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x09, 0x01, 0x00, 0x06,
18+
0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x2f, 0x09, 0x70, 0x72, 0x6f,
19+
0x64, 0x75, 0x63, 0x65, 0x72, 0x73, 0x01, 0x0c, 0x70, 0x72, 0x6f, 0x63,
20+
0x65, 0x73, 0x73, 0x65, 0x64, 0x2d, 0x62, 0x79, 0x01, 0x05, 0x63, 0x6c,
21+
0x61, 0x6e, 0x67, 0x0f, 0x31, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x34,
22+
0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x31
23+
]);
24+
25+
// Do not use isMainThread so that this test itself can be run inside a Worker.
26+
if (!process.env.HAS_STARTED_WORKER) {
27+
process.env.HAS_STARTED_WORKER = 1;
28+
const worker = new Worker(__filename);
29+
worker.once('message', (message) => {
30+
assert.strictEqual(message, 'start');
31+
setTimeout(() => worker.terminate(), common.platformTimeout(50));
32+
});
33+
} else {
34+
go();
35+
}
36+
37+
async function go() {
38+
const wasi = new WASI({ returnOnExit: true });
39+
const imports = { wasi_snapshot_preview1: wasi.wasiImport };
40+
const module = await WebAssembly.compile(bytecode);
41+
const instance = await WebAssembly.instantiate(module, imports);
42+
parentPort.postMessage('start');
43+
wasi.start(instance);
44+
}

0 commit comments

Comments
 (0)