Skip to content

Commit 801e663

Browse files
authored
Add native wrapper for dbg() JS function (#18619)
This means we can remove some complexity from the debug system in `dynlink.c` and other native callers of this function get, for example, the current thread into prepended to the debug message.
1 parent a9aa709 commit 801e663

File tree

9 files changed

+60
-14
lines changed

9 files changed

+60
-14
lines changed

src/library.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,20 +3411,21 @@ mergeInto(LibraryManager.library, {
34113411

34123412
_emscripten_out__sig: 'vp',
34133413
_emscripten_out: function(str) {
3414-
#if ASSERTIONS
3415-
assert(typeof str == 'number');
3416-
#endif
34173414
out(UTF8ToString(str));
34183415
},
34193416

34203417
_emscripten_err__sig: 'vp',
34213418
_emscripten_err: function(str) {
3422-
#if ASSERTIONS
3423-
assert(typeof str == 'number');
3424-
#endif
34253419
err(UTF8ToString(str));
34263420
},
34273421

3422+
#if ASSERTIONS || RUNTIME_DEBUG
3423+
_emscripten_dbg__sig: 'vp',
3424+
_emscripten_dbg: function(str) {
3425+
dbg(UTF8ToString(str));
3426+
},
3427+
#endif
3428+
34283429
// Use program_invocation_short_name and program_invocation_name in compiled
34293430
// programs. This function is for implementing them.
34303431
_emscripten_get_progname__sig: 'vpp',

src/runtime_debug.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,14 @@ function prettyPrint(arg) {
129129
#if ASSERTIONS || RUNTIME_DEBUG
130130
// Used by XXXXX_DEBUG settings to output debug messages.
131131
function dbg(text) {
132-
// TODO(sbc): Make this configurable somehow. Its not always convient for
132+
#if ENVIRONMENT_MAY_BE_NODE && USE_PTHREADS
133+
// Avoid using the console for debugging in multi-threaded node applications
134+
// See https://github.com/emscripten-core/emscripten/issues/14804
135+
if (ENVIRONMENT_IS_NODE) {
136+
fs.writeSync(2, text + '\n');
137+
} else
138+
#endif
139+
// TODO(sbc): Make this configurable somehow. Its not always convenient for
133140
// logging to show up as errors.
134141
console.error(text);
135142
}

src/runtime_strings.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) {
105105
* @return {string}
106106
*/
107107
function UTF8ToString(ptr, maxBytesToRead) {
108+
#if ASSERTIONS
109+
assert(typeof ptr == 'number');
110+
#endif
108111
#if CAN_ADDRESS_2GB
109112
ptr >>>= 0;
110113
#endif

src/worker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ function handleMessage(e) {
177177

178178
{{{ makeAsmImportsAccessInPthread('buffer') }}} = {{{ makeAsmImportsAccessInPthread('wasmMemory') }}}.buffer;
179179

180-
#if PTHREADS_DEBUG
180+
#if ASSERTIONS
181181
Module['workerID'] = e.data.workerID;
182182
#endif
183183

system/include/emscripten/console.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ void emscripten_console_error(const char *utf8String);
2525
// See https://github.com/emscripten-core/emscripten/issues/14804
2626
void _emscripten_out(const char *utf8String);
2727
void _emscripten_err(const char *utf8String);
28+
void _emscripten_dbg(const char *utf8String);
2829

2930
// Similar to the above functions but operate with printf-like semantics.
3031
void emscripten_console_logf(const char *utf8String, ...) __attribute__((__format__(printf, 1, 2)));
3132
void emscripten_console_warnf(const char *utf8String, ...) __attribute__((__format__(printf, 1, 2)));
3233
void emscripten_console_errorf(const char *utf8String, ...)__attribute__((__format__(printf, 1, 2)));
3334
void _emscripten_outf(const char *utf8String, ...) __attribute__((__format__(printf, 1, 2)));
3435
void _emscripten_errf(const char *utf8String, ...) __attribute__((__format__(printf, 1, 2)));
36+
void _emscripten_dbgf(const char *utf8String, ...) __attribute__((__format__(printf, 1, 2)));
3537

3638
#ifdef __cplusplus
3739
}

system/lib/libc/dynlink.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
//#define DYLINK_DEBUG
2626

2727
#ifdef DYLINK_DEBUG
28-
#define dbg(fmt, ...) _emscripten_errf("%p: " fmt, pthread_self(), ##__VA_ARGS__)
28+
#define dbg(fmt, ...) _emscripten_dbgf(fmt, ##__VA_ARGS__)
2929
#else
3030
#define dbg(fmt, ...)
3131
#endif

system/lib/libc/emscripten_console.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,12 @@ void _emscripten_errf(const char* fmt, ...) {
5454
vlogf(fmt, ap, &_emscripten_err);
5555
va_end(ap);
5656
}
57+
58+
#ifndef NDEBUG
59+
void _emscripten_dbgf(const char* fmt, ...) {
60+
va_list ap;
61+
va_start(ap, fmt);
62+
vlogf(fmt, ap, &_emscripten_dbg);
63+
va_end(ap);
64+
}
65+
#endif

test/other/test_dbg.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright 2023 The Emscripten Authors. All rights reserved.
3+
* Emscripten is available under two separate licenses, the MIT license and the
4+
* University of Illinois/NCSA Open Source License. Both these licenses can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#include <stdio.h>
9+
#include <emscripten/console.h>
10+
11+
int main() {
12+
printf("hello, world!\n");
13+
#ifndef NDEBUG
14+
// This symbol is only available in debug builds (i.e. -sASSERTIONS)
15+
_emscripten_dbg("native dbg message");
16+
_emscripten_dbgf("formatted: %d", 42);
17+
#endif
18+
return 0;
19+
}

test/test_other.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12864,15 +12864,20 @@ def test_dbg(self):
1286412864
dbg('start');
1286512865
Module.onRuntimeInitialized = () => dbg('done init');
1286612866
''')
12867+
expected = '''\
12868+
start
12869+
w:0,t:0x[0-9a-fA-F]+: done init
12870+
hello, world!
12871+
w:0,t:0x[0-9a-fA-F]+: native dbg message
12872+
w:0,t:0x[0-9a-fA-F]+: formatted: 42
12873+
'''
1286712874
self.emcc_args.append('--pre-js=pre.js')
1286812875
# Verify that, after initialization, dbg() messages are prefixed with
1286912876
# worker and thread ID.
12870-
self.do_runf(test_file('hello_world.c'),
12871-
'start\nw:0,t:0x[0-9a-fA-F]+: done init\nhello, world!\n',
12872-
regex=True)
12877+
self.do_runf(test_file('other/test_dbg.c'), expected, regex=True)
1287312878

1287412879
# When assertions are disabled `dbg` function is not defined
12875-
self.do_runf(test_file('hello_world.c'),
12880+
self.do_runf(test_file('other/test_dbg.c'),
1287612881
'ReferenceError: dbg is not defined',
12877-
emcc_args=['-sASSERTIONS=0'],
12882+
emcc_args=['-DNDEBUG', '-sASSERTIONS=0'],
1287812883
assert_returncode=NON_ZERO)

0 commit comments

Comments
 (0)