Skip to content

Commit 2328a81

Browse files
authored
[WASM_WORKERS] Add err/out/dbg overrides like pthreads (#24210)
This change add two pthread debugging features to wasm workers. 1. Under now out/err/dbg all get writting using fs.writeSync rather than going via console. 2. dbg/err messages get prefixed with the ID of the calling thread.
1 parent 9145c80 commit 2328a81

9 files changed

+104
-52
lines changed

src/lib/libpthread.js

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,33 +86,8 @@ var LibraryPThread = {
8686
pthreads: {},
8787
#if ASSERTIONS
8888
nextWorkerID: 1,
89-
debugInit() {
90-
function pthreadLogPrefix() {
91-
var t = 0;
92-
if (runtimeInitialized && typeof _pthread_self != 'undefined'
93-
#if EXIT_RUNTIME
94-
&& !runtimeExited
95-
#endif
96-
) {
97-
t = _pthread_self();
98-
}
99-
return `w:${workerID},t:${ptrToString(t)}:`;
100-
}
101-
102-
// Prefix all err()/dbg() messages with the calling thread ID.
103-
var origDbg = dbg;
104-
dbg = (...args) => origDbg(pthreadLogPrefix(), ...args);
105-
#if PTHREADS_DEBUG
106-
// With PTHREADS_DEBUG also prefix all err() messages.
107-
var origErr = err;
108-
err = (...args) => origErr(pthreadLogPrefix(), ...args);
109-
#endif
110-
},
11189
#endif
11290
init() {
113-
#if ASSERTIONS
114-
PThread.debugInit();
115-
#endif
11691
if ({{{ ENVIRONMENT_IS_MAIN_THREAD() }}}) {
11792
PThread.initMainThread();
11893
}

src/runtime_debug.js

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@
44
* SPDX-License-Identifier: MIT
55
*/
66

7+
#if ASSERTIONS || RUNTIME_DEBUG || AUTODEBUG
8+
var runtimeDebug = true; // Switch to false at runtime to disable logging at the right times
9+
10+
// Used by XXXXX_DEBUG settings to output debug messages.
11+
function dbg(...args) {
12+
if (!runtimeDebug && typeof runtimeDebug != 'undefined') return;
13+
#if ENVIRONMENT_MAY_BE_NODE && (PTHREADS || WASM_WORKERS)
14+
// Avoid using the console for debugging in multi-threaded node applications
15+
// See https://github.com/emscripten-core/emscripten/issues/14804
16+
if (ENVIRONMENT_IS_NODE) {
17+
// TODO(sbc): Unify with err/out implementation in shell.sh.
18+
var fs = require('fs');
19+
var utils = require('util');
20+
var stringify = (a) => typeof a == 'object' ? utils.inspect(a) : a;
21+
fs.writeSync(1, args.map(stringify).join(' ') + '\n');
22+
} else
23+
#endif
24+
// TODO(sbc): Make this configurable somehow. Its not always convenient for
25+
// logging to show up as warnings.
26+
console.warn(...args);
27+
}
28+
#endif
29+
730
#if ASSERTIONS
831

932
// Endianness check
@@ -129,6 +152,45 @@ function unexportedRuntimeSymbol(sym) {
129152
}
130153
}
131154

155+
#if WASM_WORKERS || PTHREADS
156+
/**
157+
* Override `err`/`out`/`dbg` to report thread / worker information
158+
*/
159+
function initWorkerLogging() {
160+
function getLogPrefix() {
161+
#if WASM_WORKERS
162+
if (Module['$ww']) {
163+
return `ww:${Module['$ww']}:`
164+
}
165+
#endif
166+
#if PTHREADS
167+
var t = 0;
168+
if (runtimeInitialized && typeof _pthread_self != 'undefined'
169+
#if EXIT_RUNTIME
170+
&& !runtimeExited
171+
#endif
172+
) {
173+
t = _pthread_self();
174+
}
175+
return `w:${workerID},t:${ptrToString(t)}:`;
176+
#else
177+
return `ww:0:`;
178+
#endif
179+
}
180+
181+
// Prefix all dbg() messages with the calling thread info.
182+
var origDbg = dbg;
183+
dbg = (...args) => origDbg(getLogPrefix(), ...args);
184+
#if RUNTIME_DEBUG
185+
// With RUNTIME_DEBUG also prefix all err() messages.
186+
var origErr = err;
187+
err = (...args) => origErr(getLogPrefix(), ...args);
188+
#endif
189+
}
190+
191+
initWorkerLogging();
192+
#endif
193+
132194
#if ASSERTIONS == 2
133195

134196
var MAX_UINT8 = (2 ** 8) - 1;
@@ -186,26 +248,3 @@ function prettyPrint(arg) {
186248
return arg;
187249
}
188250
#endif
189-
190-
#if ASSERTIONS || RUNTIME_DEBUG || AUTODEBUG
191-
var runtimeDebug = true; // Switch to false at runtime to disable logging at the right times
192-
193-
// Used by XXXXX_DEBUG settings to output debug messages.
194-
function dbg(...args) {
195-
if (!runtimeDebug && typeof runtimeDebug != 'undefined') return;
196-
#if ENVIRONMENT_MAY_BE_NODE && (PTHREADS || WASM_WORKERS)
197-
// Avoid using the console for debugging in multi-threaded node applications
198-
// See https://github.com/emscripten-core/emscripten/issues/14804
199-
if (ENVIRONMENT_IS_NODE) {
200-
// TODO(sbc): Unify with err/out implementation in shell.sh.
201-
var fs = require('fs');
202-
var utils = require('util');
203-
var stringify = (a) => typeof a == 'object' ? utils.inspect(a) : a;
204-
fs.writeSync(1, args.map(stringify).join(' ') + '\n');
205-
} else
206-
#endif
207-
// TODO(sbc): Make this configurable somehow. Its not always convenient for
208-
// logging to show up as warnings.
209-
console.warn(...args);
210-
}
211-
#endif

src/shell.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ if (!ENVIRONMENT_IS_AUDIO_WORKLET)
377377
#endif // ASSERTIONS
378378
}
379379

380-
#if ENVIRONMENT_MAY_BE_NODE && PTHREADS
380+
#if ENVIRONMENT_MAY_BE_NODE && (PTHREADS || WASM_WORKERS)
381381
// Set up the out() and err() hooks, which are how we can print to stdout or
382382
// stderr, respectively.
383383
// Normally just binding console.log/console.error here works fine, but
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
53602
1+
53603
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
51652
1+
51653

test/test_other.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14594,6 +14594,9 @@ def test_wasm_worker_trusted_types(self):
1459414594
def test_wasm_worker_terminate(self):
1459514595
self.do_runf('wasm_worker/terminate_wasm_worker.c', emcc_args=['-sWASM_WORKERS'])
1459614596

14597+
def test_wasm_worker_dbg(self):
14598+
self.do_run_in_out_file_test('wasm_worker/test_wasm_worker_dbg.c', emcc_args=['-sWASM_WORKERS'])
14599+
1459714600
@also_with_minimal_runtime
1459814601
def test_wasm_worker_closure(self):
1459914602
self.run_process([EMCC, test_file('wasm_worker/lock_async_acquire.c'), '-O2', '-sWASM_WORKERS', '--closure=1'])

test/wasm_worker/hello_wasm_worker.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void do_exit() {
1212
}
1313

1414
void run_in_worker() {
15-
emscripten_out("Hello from wasm worker!\n");
15+
emscripten_out("Hello from wasm worker!");
1616
EM_ASM(typeof checkStackCookie == 'function' && checkStackCookie());
1717
emscripten_wasm_worker_post_function_v(EMSCRIPTEN_WASM_WORKER_ID_PARENT, do_exit);
1818
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <emscripten/emscripten.h>
2+
#include <emscripten/console.h>
3+
#include <emscripten/em_asm.h>
4+
#include <emscripten/wasm_worker.h>
5+
#include <assert.h>
6+
7+
// This is the code example in site/source/docs/api_reference/wasm_workers.rst
8+
void do_exit() {
9+
emscripten_out("do_exit");
10+
emscripten_terminate_all_wasm_workers();
11+
emscripten_force_exit(0);
12+
}
13+
14+
void run_in_worker() {
15+
emscripten_out("Hello from wasm worker!");
16+
emscripten_err("err from wasm worker");
17+
emscripten_dbg("dbg from wasm worker");
18+
EM_ASM(typeof checkStackCookie == 'function' && checkStackCookie());
19+
emscripten_wasm_worker_post_function_v(EMSCRIPTEN_WASM_WORKER_ID_PARENT, do_exit);
20+
}
21+
22+
int main() {
23+
emscripten_err("err from main thread");
24+
emscripten_dbg("dbg from main thread");
25+
emscripten_wasm_worker_t worker = emscripten_malloc_wasm_worker(/*stack size: */1024);
26+
assert(worker);
27+
emscripten_wasm_worker_post_function_v(worker, run_in_worker);
28+
emscripten_exit_with_live_runtime();
29+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
err from main thread
2+
ww:0: dbg from main thread
3+
Hello from wasm worker!
4+
err from wasm worker
5+
ww:1: dbg from wasm worker
6+
do_exit

0 commit comments

Comments
 (0)