Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[browser][MT] withDumpThreadsOnNonZeroExit #98052

Merged
merged 8 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/mono/browser/runtime/cwraps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {
MonoType, MonoObjectRef, MonoStringRef, JSMarshalerArguments
} from "./types/internal";
import type { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten";
import { linkerEnableAotProfiler, linkerEnableBrowserProfiler, Module } from "./globals";
import { Module, runtimeHelpers } from "./globals";
import { mono_log_error } from "./logging";
import { mono_assert } from "./globals";

Expand Down Expand Up @@ -60,8 +60,8 @@ const fn_signatures: SigLine[] = [
[true, "mono_wasm_getenv", "number", ["string"]],
[true, "mono_wasm_set_main_args", "void", ["number", "number"]],
// These two need to be lazy because they may be missing
[() => !linkerEnableAotProfiler, "mono_wasm_profiler_init_aot", "void", ["string"]],
[() => !linkerEnableBrowserProfiler, "mono_wasm_profiler_init_aot", "void", ["string"]],
[() => !runtimeHelpers.emscriptenBuildOptions.enableAotProfiler, "mono_wasm_profiler_init_aot", "void", ["string"]],
[() => !runtimeHelpers.emscriptenBuildOptions.enableBrowserProfiler, "mono_wasm_profiler_init_aot", "void", ["string"]],
[true, "mono_wasm_profiler_init_browser", "void", ["number"]],
[false, "mono_wasm_exec_regression", "number", ["number", "string"]],
[false, "mono_wasm_invoke_method_bound", "number", ["number", "number", "number"]],
Expand Down
3 changes: 3 additions & 0 deletions src/mono/browser/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,9 @@ type RuntimeAPI = {
productVersion: string;
gitHash: string;
buildConfiguration: string;
wasmEnableThreads: boolean;
wasmEnableSIMD: boolean;
wasmEnableExceptionHandling: boolean;
};
} & APIType;
type ModuleAPI = {
Expand Down
18 changes: 4 additions & 14 deletions src/mono/browser/runtime/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,19 +189,6 @@ mono_wasm_load_runtime (const char *unused, int debug_level)
mono_wasm_link_icu_shim ();
#endif

#ifndef DISABLE_THREADS
monoeg_g_setenv ("MONO_SLEEP_ABORT_LIMIT", "5000", 0);
#endif

// monoeg_g_setenv ("DOTNET_DebugWriteToStdErr", "1", 0);

#ifdef DEBUG
// monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0);
// monoeg_g_setenv ("MONO_LOG_MASK", "gc", 0);
// Setting this env var allows Diagnostic.Debug to write to stderr. In a browser environment this
// output will be sent to the console. Right now this is the only way to emit debug logging from
// corlib assemblies.
#endif
// When the list of app context properties changes, please update RuntimeConfigReservedProperties for
// target _WasmGenerateRuntimeConfig in BrowserWasmApp.targets file
const char *appctx_keys[2];
Expand Down Expand Up @@ -372,7 +359,10 @@ mono_wasm_exec_regression (int verbose_level, char *image)
EMSCRIPTEN_KEEPALIVE int
mono_wasm_exit (int exit_code)
{
mono_jit_cleanup (root_domain);
if (exit_code == 0)
{
mono_jit_cleanup (root_domain);
}
fflush (stdout);
fflush (stderr);
emscripten_force_exit (exit_code);
Expand Down
18 changes: 9 additions & 9 deletions src/mono/browser/runtime/es6/dotnet.es6.lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const RUN_AOT_COMPILATION = process.env.RUN_AOT_COMPILATION === "1";
var methodIndexByName = undefined;
var gitHash = undefined;

function setup(linkerSetup) {
function setup(emscriptenBuildOptions) {
// USE_PTHREADS is emscripten's define symbol, which is passed to acorn optimizer, so we could use it here
#if USE_PTHREADS
const modulePThread = PThread;
Expand Down Expand Up @@ -43,8 +43,7 @@ function setup(linkerSetup) {
updateMemoryViews,
getMemory: () => { return wasmMemory; },
getWasmIndirectFunctionTable: () => { return wasmTable; },
...linkerSetup
});
}, emscriptenBuildOptions);

#if USE_PTHREADS
if (ENVIRONMENT_IS_PTHREAD) {
Expand Down Expand Up @@ -83,11 +82,12 @@ function injectDependencies() {
#endif

DotnetSupportLib["$DOTNET__postset"] = `DOTNET.setup({ ` +
`linkerWasmEnableSIMD: ${WASM_ENABLE_SIMD ? "true" : "false"},` +
`linkerWasmEnableEH: ${WASM_ENABLE_EH ? "true" : "false"},` +
`linkerEnableAotProfiler: ${ENABLE_AOT_PROFILER ? "true" : "false"}, ` +
`linkerEnableBrowserProfiler: ${ENABLE_BROWSER_PROFILER ? "true" : "false"}, ` +
`linkerRunAOTCompilation: ${RUN_AOT_COMPILATION ? "true" : "false"}, ` +
`wasmEnableSIMD: ${WASM_ENABLE_SIMD ? "true" : "false"},` +
`wasmEnableEH: ${WASM_ENABLE_EH ? "true" : "false"},` +
`enableAotProfiler: ${ENABLE_AOT_PROFILER ? "true" : "false"}, ` +
`enableBrowserProfiler: ${ENABLE_BROWSER_PROFILER ? "true" : "false"}, ` +
`runAOTCompilation: ${RUN_AOT_COMPILATION ? "true" : "false"}, ` +
`wasmEnableThreads: ${USE_PTHREADS ? "true" : "false"}, ` +
`gitHash: "${gitHash}", ` +
`});`;

Expand All @@ -96,4 +96,4 @@ function injectDependencies() {
}


// var methodIndexByName wil be appended below by the MSBuild in browser.proj
// var methodIndexByName wil be appended below by the MSBuild in browser.proj via exports-linker.ts
4 changes: 3 additions & 1 deletion src/mono/browser/runtime/exports-binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { mono_interp_jit_wasm_entry_trampoline, mono_interp_record_interp_entry
import { mono_interp_jit_wasm_jit_call_trampoline, mono_interp_invoke_wasm_jit_call_trampoline, mono_interp_flush_jitcall_queue } from "./jiterpreter-jit-call";
import { mono_wasm_resolve_or_reject_promise } from "./marshal-to-js";
import { mono_wasm_eventloop_has_unsettled_interop_promises } from "./pthreads/shared/eventloop";
import { mono_wasm_pthread_on_pthread_attached, mono_wasm_pthread_on_pthread_unregistered, mono_wasm_pthread_on_pthread_registered } from "./pthreads/worker";
import { mono_wasm_pthread_on_pthread_attached, mono_wasm_pthread_on_pthread_unregistered, mono_wasm_pthread_on_pthread_registered, mono_wasm_pthread_set_name } from "./pthreads/worker";
import { mono_wasm_schedule_timer, schedule_background_exec } from "./scheduling";
import { mono_wasm_asm_loaded } from "./startup";
import { mono_wasm_diagnostic_server_on_server_thread_created } from "./diagnostics/server_pthread";
Expand All @@ -37,6 +37,8 @@ export const mono_wasm_threads_imports = !WasmEnableThreads ? [] : [
mono_wasm_pthread_on_pthread_registered,
mono_wasm_pthread_on_pthread_attached,
mono_wasm_pthread_on_pthread_unregistered,
mono_wasm_pthread_set_name,

// threads.c
mono_wasm_eventloop_has_unsettled_interop_promises,
// diagnostics_server.c
Expand Down
15 changes: 14 additions & 1 deletion src/mono/browser/runtime/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

import ProductVersion from "consts:productVersion";
import BuildConfiguration from "consts:configuration";
import WasmEnableThreads from "consts:wasmEnableThreads";
import WasmEnableSIMD from "consts:wasmEnableSIMD";
import WasmEnableExceptionHandling from "consts:wasmEnableExceptionHandling";

import type { RuntimeAPI } from "./types";

import { Module, exportedRuntimeAPI, loaderHelpers, passEmscriptenInternals, runtimeHelpers, setRuntimeGlobals, } from "./globals";
Expand All @@ -18,6 +22,7 @@ import { mono_wasm_stringify_as_error_with_stack } from "./logging";
import { instantiate_asset, instantiate_symbols_asset, instantiate_segmentation_rules_asset } from "./assets";
import { jiterpreter_dump_stats } from "./jiterpreter";
import { forceDisposeProxies } from "./gc-handles";
import { dumpThreads } from "./pthreads/browser";

export let runtimeList: RuntimeList;

Expand All @@ -35,6 +40,11 @@ function initializeExports(globalObjects: GlobalObjects): RuntimeAPI {
forceDisposeProxies,
instantiate_segmentation_rules_asset,
});
if (WasmEnableThreads) {
Object.assign(runtimeHelpers, {
dumpThreads,
});
}

const API = export_api();
Object.assign(exportedRuntimeAPI, {
Expand All @@ -43,7 +53,10 @@ function initializeExports(globalObjects: GlobalObjects): RuntimeAPI {
runtimeBuildInfo: {
productVersion: ProductVersion,
gitHash: runtimeHelpers.gitHash,
buildConfiguration: BuildConfiguration
buildConfiguration: BuildConfiguration,
wasmEnableThreads: WasmEnableThreads,
wasmEnableSIMD: WasmEnableSIMD,
wasmEnableExceptionHandling: WasmEnableExceptionHandling,
},
...API,
});
Expand Down
17 changes: 4 additions & 13 deletions src/mono/browser/runtime/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import gitHash from "consts:gitHash";

import { RuntimeAPI } from "./types/index";
import type { GlobalObjects, EmscriptenInternals, RuntimeHelpers, LoaderHelpers, DotnetModuleInternal, PromiseAndController } from "./types/internal";
import type { GlobalObjects, EmscriptenInternals, RuntimeHelpers, LoaderHelpers, DotnetModuleInternal, PromiseAndController, EmscriptenBuildOptions } from "./types/internal";
import { mono_log_error } from "./logging";

// these are our public API (except internal)
Expand All @@ -30,23 +30,14 @@ export let exportedRuntimeAPI: RuntimeAPI = null as any;
export let runtimeHelpers: RuntimeHelpers = null as any;
export let loaderHelpers: LoaderHelpers = null as any;

export let linkerWasmEnableSIMD = true;
export let linkerWasmEnableEH = true;
export let linkerEnableAotProfiler = false;
export let linkerEnableBrowserProfiler = false;
export let linkerRunAOTCompilation = false;
export let _runtimeModuleLoaded = false; // please keep it in place also as rollup guard

export function passEmscriptenInternals(internals: EmscriptenInternals): void {
export function passEmscriptenInternals(internals: EmscriptenInternals, emscriptenBuildOptions: EmscriptenBuildOptions): void {
runtimeHelpers.emscriptenBuildOptions = emscriptenBuildOptions;

ENVIRONMENT_IS_PTHREAD = internals.isPThread;
linkerWasmEnableSIMD = internals.linkerWasmEnableSIMD;
linkerWasmEnableEH = internals.linkerWasmEnableEH;
linkerEnableAotProfiler = internals.linkerEnableAotProfiler;
linkerEnableBrowserProfiler = internals.linkerEnableBrowserProfiler;
linkerRunAOTCompilation = internals.linkerRunAOTCompilation;
runtimeHelpers.quit = internals.quit_;
runtimeHelpers.ExitStatus = internals.ExitStatus;
runtimeHelpers.moduleGitHash = internals.gitHash;
runtimeHelpers.getMemory = internals.getMemory;
runtimeHelpers.getWasmIndirectFunctionTable = internals.getWasmIndirectFunctionTable;
runtimeHelpers.updateMemoryViews = internals.updateMemoryViews;
Expand Down
6 changes: 3 additions & 3 deletions src/mono/browser/runtime/jiterpreter-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import WasmEnableThreads from "consts:wasmEnableThreads";
import { NativePointer, ManagedPointer, VoidPtr } from "./types/emscripten";
import { Module, mono_assert, runtimeHelpers, linkerRunAOTCompilation } from "./globals";
import { Module, mono_assert, runtimeHelpers } from "./globals";
import { WasmOpcode, WasmSimdOpcode, WasmValtype } from "./jiterpreter-opcodes";
import { MintOpcode } from "./mintops";
import cwraps from "./cwraps";
Expand Down Expand Up @@ -2017,8 +2017,8 @@ export function jiterpreter_allocate_tables() {
// then create special placeholder functions that examine the rmethod to determine which kind
// of method is being called.
const traceTableSize = options.tableSize,
jitCallTableSize = linkerRunAOTCompilation ? options.tableSize : 1,
interpEntryTableSize = linkerRunAOTCompilation ? options.aotTableSize : 1,
jitCallTableSize = runtimeHelpers.emscriptenBuildOptions.runAOTCompilation ? options.tableSize : 1,
interpEntryTableSize = runtimeHelpers.emscriptenBuildOptions.runAOTCompilation ? options.aotTableSize : 1,
numInterpEntryTables = JiterpreterTable.LAST - JiterpreterTable.InterpEntryStatic0 + 1,
totalSize = traceTableSize + jitCallTableSize + (numInterpEntryTables * interpEntryTableSize) + 1,
wasmTable = getWasmFunctionTable();
Expand Down
8 changes: 7 additions & 1 deletion src/mono/browser/runtime/loader/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,22 @@ export function normalizeConfig() {
config.pthreadPoolSize = 7;
}

// this is how long the Mono GC will try to wait for all threads to be suspended before it gives up and aborts the process
if (WasmEnableThreads && config.environmentVariables["MONO_SLEEP_ABORT_LIMIT"] === undefined) {
config.environmentVariables["MONO_SLEEP_ABORT_LIMIT"] = "5000";
pavelsavara marked this conversation as resolved.
Show resolved Hide resolved
}

// Default values (when WasmDebugLevel is not set)
// - Build (debug) => debugBuild=true & debugLevel=-1 => -1
// - Build (release) => debugBuild=true & debugLevel=0 => 0
// - Publish (debug) => debugBuild=false & debugLevel=-1 => 0
// - Publish (release) => debugBuild=false & debugLevel=0 => 0
config.debugLevel = hasDebuggingEnabled(config) ? config.debugLevel : 0;

if (config.diagnosticTracing === undefined && BuildConfiguration === "Debug") {
if (BuildConfiguration === "Debug" && config.diagnosticTracing === undefined) {
config.diagnosticTracing = true;
}

if (config.applicationCulture) {
// If a culture is specified via start options use that to initialize the Emscripten \ .NET culture.
config.environmentVariables!["LANG"] = `${config.applicationCulture}.UTF-8`;
Expand Down
3 changes: 3 additions & 0 deletions src/mono/browser/runtime/loader/exit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ export function mono_exit(exit_code: number, reason?: any): void {
if (exit_code === 0 && loaderHelpers.config?.interopCleanupOnExit) {
runtimeHelpers.forceDisposeProxies(true, true);
}
if (WasmEnableThreads && exit_code !== 0 && loaderHelpers.config?.dumpThreadsOnNonZeroExit) {
runtimeHelpers.dumpThreads();
}
}
}
catch (err) {
Expand Down
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/loader/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type { MonoConfig, RuntimeAPI } from "../types";
import { assert_runtime_running, installUnhandledErrorHandler, is_exited, is_runtime_running, mono_exit } from "./exit";
import { assertIsControllablePromise, createPromiseController, getPromiseController } from "./promise-controller";
import { mono_download_assets, resolve_single_asset_path, retrieve_asset_download } from "./assets";
import { mono_log_error, mono_set_thread_name, setup_proxy_console } from "./logging";
import { mono_log_error, set_thread_prefix, setup_proxy_console } from "./logging";
import { invokeLibraryInitializers } from "./libraryInitializers";
import { deep_merge_config, hasDebuggingEnabled } from "./config";
import { logDownloadStatsToConsole, purgeUnusedCacheEntriesAsync } from "./assetsCache";
Expand Down Expand Up @@ -114,7 +114,7 @@ export function setLoaderGlobals(
mono_download_assets,
resolve_single_asset_path,
setup_proxy_console,
mono_set_thread_name,
set_thread_prefix,
logDownloadStatsToConsole,
purgeUnusedCacheEntriesAsync,
installUnhandledErrorHandler,
Expand Down
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/loader/logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ let theConsoleApi: any;
let originalConsoleMethods: any;
let threadNamePrefix: string;

export function mono_set_thread_name(threadName: string) {
threadNamePrefix = threadName;
export function set_thread_prefix(threadPrefix: string) {
threadNamePrefix = threadPrefix;
}

export function mono_log_debug(msg: string, ...data: any[]) {
Expand Down
13 changes: 13 additions & 0 deletions src/mono/browser/runtime/loader/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,19 @@ export class HostBuilder implements DotnetHostBuilder {
}
}

// internal
withDumpThreadsOnNonZeroExit(): DotnetHostBuilder {
try {
deep_merge_config(monoConfig, {
dumpThreadsOnNonZeroExit: true
});
return this;
} catch (err) {
mono_exit(1, err);
throw err;
}
}

// internal
withAssertAfterExit(): DotnetHostBuilder {
try {
Expand Down
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { CharPtr, VoidPtr } from "./types/emscripten";

let prefix = "MONO_WASM: ";

export function mono_set_thread_name(threadName: string) {
prefix = `[${threadName}] MONO_WASM: `;
export function set_thread_prefix(threadPrefix: string) {
prefix = `[${threadPrefix}] MONO_WASM: `;
}

export function mono_log_debug(msg: string, ...data: any) {
Expand Down
6 changes: 3 additions & 3 deletions src/mono/browser/runtime/profiler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import { ENVIRONMENT_IS_WEB, linkerEnableAotProfiler, linkerEnableBrowserProfiler, mono_assert, runtimeHelpers } from "./globals";
import { ENVIRONMENT_IS_WEB, mono_assert, runtimeHelpers } from "./globals";
import { MonoMethod, AOTProfilerOptions, BrowserProfilerOptions } from "./types/internal";
import { profiler_c_functions as cwraps } from "./cwraps";
import { utf8ToString } from "./strings";
Expand All @@ -15,7 +15,7 @@ import { utf8ToString } from "./strings";
// DumpAotProfileData stores the data into INTERNAL.aotProfileData.
//
export function mono_wasm_init_aot_profiler(options: AOTProfilerOptions): void {
mono_assert(linkerEnableAotProfiler, "AOT profiler is not enabled, please use <WasmProfilers>aot;</WasmProfilers> in your project file.");
mono_assert(runtimeHelpers.emscriptenBuildOptions.enableAotProfiler, "AOT profiler is not enabled, please use <WasmProfilers>aot;</WasmProfilers> in your project file.");
if (options == null)
options = {};
if (!("writeAt" in options))
Expand All @@ -27,7 +27,7 @@ export function mono_wasm_init_aot_profiler(options: AOTProfilerOptions): void {
}

export function mono_wasm_init_browser_profiler(options: BrowserProfilerOptions): void {
mono_assert(linkerEnableBrowserProfiler, "Browser profiler is not enabled, please use <WasmProfilers>browser;</WasmProfilers> in your project file.");
mono_assert(runtimeHelpers.emscriptenBuildOptions.enableBrowserProfiler, "Browser profiler is not enabled, please use <WasmProfilers>browser;</WasmProfilers> in your project file.");
if (options == null)
options = {};
const arg = "browser:";
Expand Down
Loading
Loading