Skip to content

Commit 7dc5c3a

Browse files
committed
rebase
1 parent bc2bd2b commit 7dc5c3a

16 files changed

+169
-93
lines changed

src/mono/browser/browser.proj

+1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@
206206
<EmccExportedFunction Include="stackAlloc" />
207207
<EmccExportedFunction Include="stackRestore" />
208208
<EmccExportedFunction Include="stackSave" />
209+
<EmccExportedFunction Include="_emscripten_force_exit" />
209210
</ItemGroup>
210211
<!-- for the jiterpreter -->
211212
<ItemGroup>

src/mono/browser/runtime/cwraps.ts

-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ const fn_signatures: SigLine[] = [
6363
[true, "mono_wasm_intern_string_ref", "void", ["number"]],
6464

6565
[false, "mono_wasm_exit", "void", ["number"]],
66-
[false, "mono_wasm_abort", "void", []],
6766
[true, "mono_wasm_getenv", "number", ["string"]],
6867
[true, "mono_wasm_set_main_args", "void", ["number", "number"]],
6968
// These two need to be lazy because they may be missing
@@ -192,7 +191,6 @@ export interface t_Cwraps {
192191
mono_wasm_intern_string_ref(strRef: MonoStringRef): void;
193192

194193
mono_wasm_exit(exit_code: number): void;
195-
mono_wasm_abort(): void;
196194
mono_wasm_getenv(name: string): CharPtr;
197195
mono_wasm_set_main_args(argc: number, argv: VoidPtr): void;
198196
mono_wasm_exec_regression(verbose_level: number, image: string): number;

src/mono/browser/runtime/driver.c

-6
Original file line numberDiff line numberDiff line change
@@ -347,12 +347,6 @@ mono_wasm_exit (int exit_code)
347347
emscripten_force_exit (exit_code);
348348
}
349349

350-
EMSCRIPTEN_KEEPALIVE int
351-
mono_wasm_abort ()
352-
{
353-
abort ();
354-
}
355-
356350
EMSCRIPTEN_KEEPALIVE void
357351
mono_wasm_set_main_args (int argc, char* argv[])
358352
{

src/mono/browser/runtime/invoke-js.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export function mono_wasm_invoke_jsimport_MT (signature: JSFunctionSignature, ar
6060
}
6161
return;
6262
} catch (ex2: any) {
63-
runtimeHelpers.nativeExit(ex2);
63+
runtimeHelpers.nativeAbort(ex2);
6464
return;
6565
}
6666
}

src/mono/browser/runtime/loader/exit.ts

+38-23
Original file line numberDiff line numberDiff line change
@@ -39,36 +39,40 @@ export function uninstallUnhandledErrorHandler () {
3939
}
4040
}
4141

42+
let originalOnAbort: ((reason: any, extraJson?:string)=>void)|undefined;
43+
let originalOnExit: ((code: number)=>void)|undefined;
44+
4245
export function registerEmscriptenExitHandlers () {
43-
if (!emscriptenModule.onAbort) {
44-
emscriptenModule.onAbort = onAbort;
45-
}
46-
if (!emscriptenModule.onExit) {
47-
emscriptenModule.onExit = onExit;
48-
}
46+
originalOnAbort = emscriptenModule.onAbort;
47+
originalOnExit = emscriptenModule.onExit;
48+
emscriptenModule.onAbort = onAbort;
49+
emscriptenModule.onExit = onExit;
4950
}
5051

5152
function unregisterEmscriptenExitHandlers () {
5253
if (emscriptenModule.onAbort == onAbort) {
53-
emscriptenModule.onAbort = undefined;
54+
emscriptenModule.onAbort = originalOnAbort;
5455
}
5556
if (emscriptenModule.onExit == onExit) {
56-
emscriptenModule.onExit = undefined;
57+
emscriptenModule.onExit = originalOnExit;
5758
}
5859
}
5960
function onExit (code: number) {
61+
if (originalOnExit) {
62+
originalOnExit(code);
63+
}
6064
mono_exit(code, loaderHelpers.exitReason);
6165
}
6266

6367
function onAbort (reason: any) {
64-
mono_exit(1, loaderHelpers.exitReason || reason);
68+
if (originalOnAbort) {
69+
originalOnAbort(reason || loaderHelpers.exitReason);
70+
}
71+
mono_exit(1, reason || loaderHelpers.exitReason);
6572
}
6673

6774
// this will also call mono_wasm_exit if available, which will call exitJS -> _proc_exit -> terminateAllThreads
6875
export function mono_exit (exit_code: number, reason?: any): void {
69-
unregisterEmscriptenExitHandlers();
70-
uninstallUnhandledErrorHandler();
71-
7276
// unify shape of the reason object
7377
const is_object = reason && typeof reason === "object";
7478
exit_code = (is_object && typeof reason.status === "number")
@@ -82,23 +86,24 @@ export function mono_exit (exit_code: number, reason?: any): void {
8286
reason = is_object
8387
? reason
8488
: (runtimeHelpers.ExitStatus
85-
? new runtimeHelpers.ExitStatus(exit_code)
89+
? createExitStatus(exit_code, message)
8690
: new Error("Exit with code " + exit_code + " " + message));
8791
reason.status = exit_code;
8892
if (!reason.message) {
8993
reason.message = message;
9094
}
9195

9296
// force stack property to be generated before we shut down managed code, or create current stack if it doesn't exist
93-
if (!reason.stack) {
94-
reason.stack = new Error().stack || "";
95-
}
97+
reason.stack = "" + new Error().stack || "";
9698

9799
// don't report this error twice
100+
const alreadySilent = !!reason.silent;
98101
reason.silent = true;
99102

100103
if (!is_exited()) {
101104
try {
105+
unregisterEmscriptenExitHandlers();
106+
uninstallUnhandledErrorHandler();
102107
if (!runtimeHelpers.runtimeReady) {
103108
mono_log_debug("abort_startup, reason: " + reason);
104109
abort_promises(reason);
@@ -119,19 +124,25 @@ export function mono_exit (exit_code: number, reason?: any): void {
119124
}
120125

121126
try {
122-
logOnExit(exit_code, reason);
123-
appendElementOnExit(exit_code);
127+
if (!alreadySilent) {
128+
logOnExit(exit_code, reason);
129+
appendElementOnExit(exit_code);
130+
}
124131
} catch (err) {
125132
mono_log_warn("mono_exit failed", err);
126133
// don't propagate any failures
127134
}
128135

129136
loaderHelpers.exitCode = exit_code;
130-
loaderHelpers.exitReason = reason.message;
137+
if (!loaderHelpers.exitReason) {
138+
loaderHelpers.exitReason = reason;
139+
}
131140

132141
if (!ENVIRONMENT_IS_WORKER && runtimeHelpers.runtimeReady) {
133142
emscriptenModule.runtimeKeepalivePop();
134143
}
144+
} else {
145+
mono_log_debug("mono_exit called after exit");
135146
}
136147

137148
if (loaderHelpers.config && loaderHelpers.config.asyncFlushOnExit && exit_code === 0) {
@@ -154,13 +165,11 @@ export function mono_exit (exit_code: number, reason?: any): void {
154165
function set_exit_code_and_quit_now (exit_code: number, reason?: any): void {
155166
if (WasmEnableThreads && ENVIRONMENT_IS_WORKER && runtimeHelpers.runtimeReady && runtimeHelpers.nativeAbort) {
156167
// note that the reason is not passed to UI thread
157-
runtimeHelpers.runtimeReady = false;
158168
runtimeHelpers.nativeAbort(reason);
159169
throw reason;
160170
}
161171

162172
if (runtimeHelpers.runtimeReady && runtimeHelpers.nativeExit) {
163-
runtimeHelpers.runtimeReady = false;
164173
try {
165174
runtimeHelpers.nativeExit(exit_code);
166175
} catch (error: any) {
@@ -205,7 +214,6 @@ async function flush_node_streams () {
205214
}
206215

207216
function abort_promises (reason: any) {
208-
loaderHelpers.exitReason = reason;
209217
loaderHelpers.allDownloadsQueued.promise_control.reject(reason);
210218
loaderHelpers.afterConfigLoaded.promise_control.reject(reason);
211219
loaderHelpers.wasmCompilePromise.promise_control.reject(reason);
@@ -256,7 +264,7 @@ function logOnExit (exit_code: number, reason: any) {
256264
}
257265
}
258266
}
259-
if (loaderHelpers.config) {
267+
if (!ENVIRONMENT_IS_WORKER && loaderHelpers.config) {
260268
if (loaderHelpers.config.logExitCode) {
261269
if (loaderHelpers.config.forwardConsoleLogsToWS) {
262270
teardown_proxy_console("WASM EXIT " + exit_code);
@@ -294,3 +302,10 @@ function fatal_handler (event: any, reason: any, type: string) {
294302
// no not re-throw from the fatal handler
295303
}
296304
}
305+
306+
function createExitStatus (status:number, message:string) {
307+
const ex = new runtimeHelpers.ExitStatus(status);
308+
ex.message = message;
309+
ex.toString = () => message;
310+
return ex;
311+
}

src/mono/browser/runtime/loader/logging.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ export function mono_log_error (msg: string, ...data: any) {
4242
if (data[0].silent) {
4343
return;
4444
}
45-
if (data[0].toString) {
46-
console.error(prefix + msg, data[0].toString());
47-
}
4845
if (data[0].toString) {
4946
console.error(prefix + msg, data[0].toString());
5047
return;
@@ -118,12 +115,13 @@ export function setup_proxy_console (id: string, console: Console, origin: strin
118115
}
119116

120117
export function teardown_proxy_console (message?: string) {
118+
let counter = 30;
121119
const stop_when_ws_buffer_empty = () => {
122120
if (!consoleWebSocket) {
123121
if (message && originalConsoleMethods) {
124122
originalConsoleMethods.log(message);
125123
}
126-
} else if (consoleWebSocket.bufferedAmount == 0) {
124+
} else if (consoleWebSocket.bufferedAmount == 0 || counter == 0) {
127125
if (message) {
128126
// tell xharness WasmTestMessagesProcessor we are done.
129127
// note this sends last few bytes into the same WS
@@ -136,6 +134,7 @@ export function teardown_proxy_console (message?: string) {
136134
consoleWebSocket.close(1000, message);
137135
(consoleWebSocket as any) = undefined;
138136
} else {
137+
counter--;
139138
globalThis.setTimeout(stop_when_ws_buffer_empty, 100);
140139
}
141140
};

src/mono/browser/runtime/logging.ts

+34-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
/* eslint-disable no-console */
5-
import { INTERNAL, runtimeHelpers, mono_assert } from "./globals";
4+
import WasmEnableThreads from "consts:wasmEnableThreads";
5+
6+
import { threads_c_functions as tcwraps } from "./cwraps";
7+
import { INTERNAL, runtimeHelpers, mono_assert, loaderHelpers, ENVIRONMENT_IS_WORKER, Module } from "./globals";
68
import { utf8ToString } from "./strings";
79
import { CharPtr, VoidPtr } from "./types/emscripten";
810

@@ -12,6 +14,7 @@ export function set_thread_prefix (threadPrefix: string) {
1214
prefix = `[${threadPrefix}] MONO_WASM: `;
1315
}
1416

17+
/* eslint-disable no-console */
1518
export function mono_log_debug (msg: string, ...data: any) {
1619
if (runtimeHelpers.diagnosticTracing) {
1720
console.debug(prefix + msg, ...data);
@@ -27,9 +30,15 @@ export function mono_log_warn (msg: string, ...data: any) {
2730
}
2831

2932
export function mono_log_error (msg: string, ...data: any) {
30-
if (data && data.length > 0 && data[0] && typeof data[0] === "object" && data[0].silent) {
33+
if (data && data.length > 0 && data[0] && typeof data[0] === "object") {
3134
// don't log silent errors
32-
return;
35+
if (data[0].silent) {
36+
return;
37+
}
38+
if (data[0].toString) {
39+
console.error(prefix + msg, data[0].toString());
40+
return;
41+
}
3342
}
3443
console.error(prefix + msg, ...data);
3544
}
@@ -123,7 +132,27 @@ export function mono_wasm_trace_logger (log_domain_ptr: CharPtr, log_level_ptr:
123132
switch (log_level) {
124133
case "critical":
125134
case "error":
126-
console.error(mono_wasm_stringify_as_error_with_stack(message));
135+
{
136+
const messageWithStack = message + "\n" + (new Error().stack);
137+
if (!loaderHelpers.exitReason) {
138+
loaderHelpers.exitReason = messageWithStack;
139+
}
140+
console.error(mono_wasm_stringify_as_error_with_stack(messageWithStack));
141+
if (WasmEnableThreads) {
142+
try {
143+
tcwraps.mono_wasm_print_thread_dump();
144+
} catch (e) {
145+
console.error("Failed to print thread dump", e);
146+
}
147+
}
148+
if (WasmEnableThreads && ENVIRONMENT_IS_WORKER) {
149+
setTimeout(() => {
150+
mono_log_error("forcing abort 3000ms after last error log message", messageWithStack);
151+
// _emscripten_force_exit is proxied to UI thread and should also arrive in spin wait loop
152+
Module._emscripten_force_exit(1);
153+
}, 3000);
154+
}
155+
}
127156
break;
128157
case "warning":
129158
console.warn(message);

src/mono/browser/runtime/managed-exports.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { assert_c_interop, assert_js_interop } from "./invoke-js";
1414
import { monoThreadInfo, mono_wasm_main_thread_ptr } from "./pthreads";
1515
import { _zero_region, copyBytes } from "./memory";
1616
import { stringToUTF8Ptr } from "./strings";
17-
import { mono_log_debug } from "./logging";
17+
import { mono_log_error } from "./logging";
1818

1919
const managedExports: ManagedExports = {} as any;
2020

@@ -269,7 +269,7 @@ export function install_main_synchronization_context (jsThreadBlockingMode: JSTh
269269
}
270270
return get_arg_gc_handle(res) as any;
271271
} catch (e) {
272-
mono_log_debug("install_main_synchronization_context failed", e);
272+
mono_log_error("install_main_synchronization_context failed", e);
273273
throw e;
274274
}
275275
}

src/mono/browser/runtime/pthreads/index.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import { mono_log_warn } from "../logging";
55
import { utf16ToString } from "../strings";
66

77
export {
8-
mono_wasm_main_thread_ptr, mono_wasm_install_js_worker_interop, mono_wasm_uninstall_js_worker_interop,
9-
mono_wasm_pthread_ptr, update_thread_info, isMonoThreadMessage, monoThreadInfo,
8+
mono_wasm_main_thread_ptr, mono_wasm_pthread_ptr,
9+
update_thread_info, isMonoThreadMessage, monoThreadInfo,
1010
} from "./shared";
11+
12+
export { mono_wasm_install_js_worker_interop, mono_wasm_uninstall_js_worker_interop } from "./worker-interop";
1113
export {
12-
mono_wasm_dump_threads, cancelThreads, is_thread_available,
14+
mono_wasm_dump_threads, postCancelThreads, terminateAllThreads, is_thread_available,
1315
populateEmscriptenPool, mono_wasm_init_threads, init_finalizer_thread,
1416
waitForThread, replaceEmscriptenPThreadUI
1517
} from "./ui-thread";

src/mono/browser/runtime/pthreads/shared.ts

+2-37
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@ import BuildConfiguration from "consts:configuration";
66

77
import type { GCHandle, MonoThreadMessage, PThreadInfo, PThreadPtr } from "../types/internal";
88

9-
import { ENVIRONMENT_IS_PTHREAD, Module, loaderHelpers, mono_assert, runtimeHelpers } from "../globals";
9+
import { Module, loaderHelpers, runtimeHelpers } from "../globals";
1010
import { set_thread_prefix } from "../logging";
11-
import { bindings_init } from "../startup";
12-
import { forceDisposeProxies } from "../gc-handles";
13-
import { monoMessageSymbol, GCHandleNull, PThreadPtrNull, WorkerToMainMessageType } from "../types/internal";
11+
import { monoMessageSymbol, PThreadPtrNull, WorkerToMainMessageType } from "../types/internal";
1412
import { threads_c_functions as tcwraps } from "../cwraps";
1513
import { forceThreadMemoryViewRefresh } from "../memory";
1614

@@ -34,39 +32,6 @@ export function isMonoThreadMessage (x: unknown): x is MonoThreadMessage {
3432
return typeof (xmsg.type) === "string" && typeof (xmsg.cmd) === "string";
3533
}
3634

37-
export function mono_wasm_install_js_worker_interop (context_gc_handle: GCHandle): void {
38-
if (!WasmEnableThreads) return;
39-
bindings_init();
40-
mono_assert(!runtimeHelpers.proxyGCHandle, "JS interop should not be already installed on this worker.");
41-
runtimeHelpers.proxyGCHandle = context_gc_handle;
42-
if (ENVIRONMENT_IS_PTHREAD) {
43-
runtimeHelpers.managedThreadTID = runtimeHelpers.currentThreadTID;
44-
runtimeHelpers.isManagedRunningOnCurrentThread = true;
45-
}
46-
Module.runtimeKeepalivePush();
47-
monoThreadInfo.isDirtyBecauseOfInterop = true;
48-
update_thread_info();
49-
if (ENVIRONMENT_IS_PTHREAD) {
50-
postMessageToMain({
51-
monoCmd: WorkerToMainMessageType.enabledInterop,
52-
info: monoThreadInfo,
53-
});
54-
}
55-
}
56-
57-
export function mono_wasm_uninstall_js_worker_interop (): void {
58-
if (!WasmEnableThreads) return;
59-
mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "JS interop is not installed on this worker.");
60-
mono_assert(runtimeHelpers.proxyGCHandle, "JSSynchronizationContext is not installed on this worker.");
61-
62-
forceDisposeProxies(true, runtimeHelpers.diagnosticTracing);
63-
Module.runtimeKeepalivePop();
64-
65-
runtimeHelpers.proxyGCHandle = GCHandleNull;
66-
runtimeHelpers.mono_wasm_bindings_is_ready = false;
67-
update_thread_info();
68-
}
69-
7035
// this is just for Debug build of the runtime, making it easier to debug worker threads
7136
export function update_thread_info (): void {
7237
if (!WasmEnableThreads) return;

0 commit comments

Comments
 (0)