diff --git a/src/mono/sample/Android/AndroidSampleApp.csproj b/src/mono/sample/Android/AndroidSampleApp.csproj
index 14fba9d69a0225..dd52a30abf241c 100644
--- a/src/mono/sample/Android/AndroidSampleApp.csproj
+++ b/src/mono/sample/Android/AndroidSampleApp.csproj
@@ -79,6 +79,8 @@
Assemblies="@(BundleAssemblies)"
MainLibraryFileName="$(AssemblyName).dll"
StripDebugSymbols="$(StripDebugSymbols)"
+ RuntimeComponents="$(RuntimeComponents)"
+ DiagnosticPorts="$(DiagnosticPorts)"
OutputDir="$(ApkDir)"
AppDir="$(PublishDir)">
diff --git a/src/mono/sample/Android/Makefile b/src/mono/sample/Android/Makefile
index aae622cb2862ed..889e31248dc18c 100644
--- a/src/mono/sample/Android/Makefile
+++ b/src/mono/sample/Android/Makefile
@@ -4,6 +4,16 @@ DOTNET := ../../../../dotnet.sh
USE_LLVM=true
AOT=false
DEPLOY_AND_RUN?=true
+RUNTIME_COMPONENTS=diagnostics_tracing
+
+#If DIAGNOSTIC_PORTS is enabled, RUNTIME_COMPONENTS must also be enabled.
+#If RUNTIME_COMPONENTS is enabled, DIAGNOSTIC_PORTS is optional.
+#If RUNTIME_COMPONENTS is enabled, DIAGNOSTIC_PORTS is disabled, use DOTNET_DiagnosticPorts when launching application to enable diagnostics.
+#RUNTIME_COMPONENTS=diagnostics_tracing
+#DIAGNOSTIC_PORTS=10.0.2.2:9000,nosuspend
+#DIAGNOSTIC_PORTS=10.0.2.2:9000,suspend
+#DIAGNOSTIC_PORTS=$(DOTNET_DiagnosticPorts)
+
all: runtimepack run
@@ -18,7 +28,9 @@ run:
/p:DeployAndRun=$(DEPLOY_AND_RUN) \
/p:ForceAOT=$(AOT) \
/p:UseLLVM=$(USE_LLVM) \
- /p:RunActivity=false
+ /p:RunActivity=false \
+ '/p:RuntimeComponents="$(RUNTIME_COMPONENTS)"' \
+ '/p:DiagnosticPorts="$(DIAGNOSTIC_PORTS)"'
clean:
rm -rf ../../../../artifacts/bin/AndroidSampleApp
diff --git a/src/mono/sample/iOS/Makefile b/src/mono/sample/iOS/Makefile
index be7c2bcefe0aa6..5cbd1277aa89a5 100644
--- a/src/mono/sample/iOS/Makefile
+++ b/src/mono/sample/iOS/Makefile
@@ -4,6 +4,14 @@ DOTNET := ../../../../dotnet.sh
USE_LLVM=true
AOT=false
+#If DIAGNOSTIC_PORTS is enabled, RUNTIME_COMPONENTS must also be enabled.
+#If RUNTIME_COMPONENTS is enabled, DIAGNOSTIC_PORTS is optional.
+#If RUNTIME_COMPONENTS is enabled, DIAGNOSTIC_PORTS is disabled, use DOTNET_DiagnosticPorts when launching application to enable diagnostics.
+#RUNTIME_COMPONENTS=diagnostics_tracing
+#DIAGNOSTIC_PORTS=127.0.0.1:9000,nosuspend
+#DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend
+#DIAGNOSTIC_PORTS=$(DOTNET_DiagnosticPorts)
+
all: runtimepack run
TOOLS_DIR=../../../tasks
@@ -15,24 +23,51 @@ runtimepack:
../../../../build.sh Mono+Libs -os iOSSimulator -arch $(MONO_ARCH) -c $(MONO_CONFIG)
run: clean appbuilder
- $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) \
- /p:UseLLVM=$(USE_LLVM) /p:ForceAOT=$(AOT)
+ $(DOTNET) publish \
+ -c $(MONO_CONFIG) \
+ /p:TargetArchitecture=$(MONO_ARCH) \
+ /p:UseLLVM=$(USE_LLVM) \
+ /p:ForceAOT=$(AOT) \
+ '/p:RuntimeComponents="$(RUNTIME_COMPONENTS)"' \
+ '/p:DiagnosticPorts="$(DIAGNOSTIC_PORTS)"'
run-sim: clean appbuilder
- $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=iOSSimulator /p:TargetArchitecture=$(MONO_ARCH) \
- /p:UseLLVM=$(USE_LLVM) /p:ForceAOT=$(AOT)
+ $(DOTNET) publish \
+ -c $(MONO_CONFIG) \
+ /p:TargetOS=iOSSimulator \
+ /p:TargetArchitecture=$(MONO_ARCH) \
+ /p:UseLLVM=$(USE_LLVM) \
+ /p:ForceAOT=$(AOT) \
+ '/p:RuntimeComponents="$(RUNTIME_COMPONENTS)"' \
+ '/p:DiagnosticPorts="$(DIAGNOSTIC_PORTS)"'
run-catalyst:
- $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=MacCatalyst /p:TargetArchitecture=$(MONO_ARCH) \
- /p:UseLLVM=False /p:ForceAOT=False
+ $(DOTNET) publish \
+ -c $(MONO_CONFIG) \
+ /p:TargetOS=MacCatalyst \
+ /p:TargetArchitecture=$(MONO_ARCH) \
+ /p:UseLLVM=False \
+ /p:ForceAOT=False
run-sim-interp: clean appbuilder
- $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=iOSSimulator /p:TargetArchitecture=$(MONO_ARCH) \
- /p:UseLLVM=$(USE_LLVM) /p:ForceAOT=$(AOT) /p:MonoForceInterpreter=true
+ $(DOTNET) publish \
+ -c $(MONO_CONFIG) \
+ /p:TargetOS=iOSSimulator \
+ /p:TargetArchitecture=$(MONO_ARCH) \
+ /p:UseLLVM=$(USE_LLVM) \
+ /p:ForceAOT=$(AOT) \
+ /p:MonoForceInterpreter=true \
+ '/p:RuntimeComponents="$(RUNTIME_COMPONENTS)"' \
+ '/p:DiagnosticPorts="$(DIAGNOSTIC_PORTS)"'
run-catalyst-interp:
- $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=MacCatalyst /p:TargetArchitecture=$(MONO_ARCH) \
- /p:UseLLVM=False /p:ForceAOT=False /p:MonoForceInterpreter=true
+ $(DOTNET) publish \
+ -c $(MONO_CONFIG) \
+ /p:TargetOS=MacCatalyst \
+ /p:TargetArchitecture=$(MONO_ARCH) \
+ /p:UseLLVM=False \
+ /p:ForceAOT=False \
+ /p:MonoForceInterpreter=true
clean:
rm -rf bin
diff --git a/src/mono/sample/iOS/Program.csproj b/src/mono/sample/iOS/Program.csproj
index 242896e764b15e..6c238dc62484df 100644
--- a/src/mono/sample/iOS/Program.csproj
+++ b/src/mono/sample/iOS/Program.csproj
@@ -84,6 +84,8 @@
Optimized="$(Optimized)"
ForceAOT="$(ForceAOT)"
ForceInterpreter="$(MonoForceInterpreter)"
+ RuntimeComponents="$(RuntimeComponents)"
+ DiagnosticPorts="$(DiagnosticPorts)"
AppDir="$(MSBuildThisFileDirectory)$(PublishDir)">
diff --git a/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs b/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs
index 20438d0bc65588..345ad7219998dc 100644
--- a/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs
+++ b/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs
@@ -43,6 +43,11 @@ public class AndroidAppBuilderTask : Task
///
public string? RuntimeComponents { get; set; } = ""!;
+ ///
+ /// Diagnostic ports configuration string
+ ///
+ public string? DiagnosticPorts { get; set; } = ""!;
+
[Required]
public string RuntimeIdentifier { get; set; } = ""!;
@@ -102,6 +107,7 @@ public override bool Execute()
apkBuilder.ForceAOT = ForceAOT;
apkBuilder.StaticLinkedRuntime = StaticLinkedRuntime;
apkBuilder.RuntimeComponents = RuntimeComponents;
+ apkBuilder.DiagnosticPorts = DiagnosticPorts;
apkBuilder.Assemblies = Assemblies;
(ApkBundlePath, ApkPackageId) = apkBuilder.BuildApk(abi, MainLibraryFileName, MonoRuntimeHeaders);
diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
index 42e5d282d2afc9..ca7c4922ddbbcb 100644
--- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs
+++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
@@ -28,6 +28,7 @@ public class ApkBuilder
public bool EnableRuntimeLogging { get; set; }
public bool StaticLinkedRuntime { get; set; }
public string? RuntimeComponents { get; set; }
+ public string? DiagnosticPorts { get; set; }
public ITaskItem[] Assemblies { get; set; } = Array.Empty();
public (string apk, string packageId) BuildApk(
@@ -79,6 +80,21 @@ public class ApkBuilder
throw new InvalidOperationException("Interpreter and AOT cannot be enabled at the same time");
}
+ if (!string.IsNullOrEmpty(DiagnosticPorts))
+ {
+ bool validDiagnosticsConfig = false;
+
+ if (string.IsNullOrEmpty(RuntimeComponents))
+ validDiagnosticsConfig = false;
+ else if (RuntimeComponents.Equals("*", StringComparison.OrdinalIgnoreCase))
+ validDiagnosticsConfig = true;
+ else if (RuntimeComponents.Contains("diagnostics_tracing", StringComparison.OrdinalIgnoreCase))
+ validDiagnosticsConfig = true;
+
+ if (!validDiagnosticsConfig)
+ throw new ArgumentException("Using DiagnosticPorts require diagnostics_tracing runtime component.");
+ }
+
// Try to get the latest build-tools version if not specified
if (string.IsNullOrEmpty(BuildToolsVersion))
BuildToolsVersion = GetLatestBuildTools(AndroidSdk);
@@ -268,6 +284,11 @@ public class ApkBuilder
defines = "add_definitions(-DFORCE_AOT=1)";
}
+ if (!string.IsNullOrEmpty(DiagnosticPorts))
+ {
+ defines += "\nadd_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")";
+ }
+
cmakeLists = cmakeLists.Replace("%Defines%", defines);
File.WriteAllText(Path.Combine(OutputDir, "CMakeLists.txt"), cmakeLists);
diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid.c b/src/tasks/AndroidAppBuilder/Templates/monodroid.c
index 17f6c2b3ad4ec0..7bd0464075ebf9 100644
--- a/src/tasks/AndroidAppBuilder/Templates/monodroid.c
+++ b/src/tasks/AndroidAppBuilder/Templates/monodroid.c
@@ -205,12 +205,20 @@ cleanup_runtime_config (MonovmRuntimeConfigArguments *args, void *user_data)
int
mono_droid_runtime_init (const char* executable, int managed_argc, char* managed_argv[])
{
+ // NOTE: these options can be set via command line args for adb or xharness, see AndroidSampleApp.csproj
+
// uncomment for debug output:
//
//setenv ("XUNIT_VERBOSE", "true", true);
//setenv ("MONO_LOG_LEVEL", "debug", true);
//setenv ("MONO_LOG_MASK", "all", true);
- // NOTE: these options can be set via command line args for adb or xharness, see AndroidSampleApp.csproj
+
+ // build using DiagnosticPorts property in AndroidAppBuilder
+ // or set DOTNET_DiagnosticPorts env via adb, xharness when undefined.
+ // NOTE, using DOTNET_DiagnosticPorts requires app build using AndroidAppBuilder and RuntimeComponents=diagnostics_tracing
+#ifdef DIAGNOSTIC_PORTS
+ setenv ("DOTNET_DiagnosticPorts", DIAGNOSTIC_PORTS, true);
+#endif
bool wait_for_debugger = false;
chdir (bundle_path);
@@ -266,14 +274,18 @@ mono_droid_runtime_init (const char* executable, int managed_argc, char* managed
mono_jit_set_aot_mode(MONO_AOT_MODE_FULL);
#endif
- mono_jit_init_version ("dotnet.android", "mobile");
+ MonoDomain *domain = mono_jit_init_version ("dotnet.android", "mobile");
+ assert (domain);
MonoAssembly *assembly = mono_droid_load_assembly (executable, NULL);
assert (assembly);
- LOG_INFO ("Executable: %s", executable);
- int res = mono_jit_exec (mono_domain_get (), assembly, managed_argc, managed_argv);
+ LOG_INFO ("Executable: %s", executable);
+ int res = mono_jit_exec (domain, assembly, managed_argc, managed_argv);
LOG_INFO ("Exit code: %d.", res);
+
+ mono_jit_cleanup (domain);
+
return res;
}
diff --git a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs
index 3f72ca56cf243e..68ce0e18500137 100644
--- a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs
+++ b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs
@@ -131,6 +131,11 @@ public string TargetOS
///
public string? RuntimeComponents { get; set; } = ""!;
+ ///
+ /// Diagnostic ports configuration string
+ ///
+ public string? DiagnosticPorts { get; set; } = ""!;
+
///
/// Forces the runtime to use the invariant mode
///
@@ -198,10 +203,26 @@ public override bool Execute()
throw new InvalidOperationException("Interpreter and AOT cannot be enabled at the same time");
}
+ if (!string.IsNullOrEmpty(DiagnosticPorts))
+ {
+ bool validDiagnosticsConfig = false;
+
+ if (string.IsNullOrEmpty(RuntimeComponents))
+ validDiagnosticsConfig = false;
+ else if (RuntimeComponents.Equals("*", StringComparison.OrdinalIgnoreCase))
+ validDiagnosticsConfig = true;
+ else if (RuntimeComponents.Contains("diagnostics_tracing", StringComparison.OrdinalIgnoreCase))
+ validDiagnosticsConfig = true;
+
+ if (!validDiagnosticsConfig)
+ throw new ArgumentException("Using DiagnosticPorts require diagnostics_tracing runtime component.");
+ }
+
if (GenerateXcodeProject)
{
Xcode generator = new Xcode(TargetOS, Arch);
generator.EnableRuntimeLogging = EnableRuntimeLogging;
+ generator.DiagnosticPorts = DiagnosticPorts;
XcodeProjectPath = generator.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles,
AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, Optimized, RuntimeComponents, NativeMainSource);
diff --git a/src/tasks/AppleAppBuilder/Templates/runtime.m b/src/tasks/AppleAppBuilder/Templates/runtime.m
index 9b90f44972db37..e45455507a138b 100644
--- a/src/tasks/AppleAppBuilder/Templates/runtime.m
+++ b/src/tasks/AppleAppBuilder/Templates/runtime.m
@@ -231,6 +231,13 @@
setenv ("MONO_LOG_MASK", "all", TRUE);
#endif
+ // build using DiagnosticPorts property in AppleAppBuilder
+ // or set DOTNET_DiagnosticPorts env via mlaunch, xharness when undefined.
+ // NOTE, using DOTNET_DiagnosticPorts requires app build using AppleAppBuilder and RuntimeComponents=diagnostics_tracing
+#ifdef DIAGNOSTIC_PORTS
+ setenv ("DOTNET_DiagnosticPorts", DIAGNOSTIC_PORTS, true);
+#endif
+
id args_array = [[NSProcessInfo processInfo] arguments];
assert ([args_array count] <= 128);
const char *managed_argv [128];
@@ -308,7 +315,9 @@
char* options[] = { "--debugger-agent=transport=dt_socket,server=y,address=0.0.0.0:55555" };
mono_jit_parse_options (1, options);
}
- mono_jit_init_version ("dotnet.ios", "mobile");
+
+ MonoDomain *domain = mono_jit_init_version ("dotnet.ios", "mobile");
+ assert (domain);
#if !FORCE_INTERPRETER && (!TARGET_OS_SIMULATOR || FORCE_AOT)
// device runtimes are configured to use lazy gc thread creation
@@ -326,5 +335,7 @@
// Print this so apps parsing logs can detect when we exited
os_log_info (OS_LOG_DEFAULT, "Exit code: %d.", res);
+ mono_jit_cleanup (domain);
+
exit (res);
}
diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs
index 6a59b718c5bc42..4409043f00a425 100644
--- a/src/tasks/AppleAppBuilder/Xcode.cs
+++ b/src/tasks/AppleAppBuilder/Xcode.cs
@@ -41,6 +41,7 @@ public Xcode(string target, string arch)
}
public bool EnableRuntimeLogging { get; set; }
+ public string? DiagnosticPorts { get; set; } = ""!;
public string GenerateXCode(
string projectName,
@@ -212,6 +213,11 @@ public string GenerateXCode(
defines.AppendLine("add_definitions(-DENABLE_RUNTIME_LOGGING=1)");
}
+ if (!string.IsNullOrEmpty(DiagnosticPorts))
+ {
+ defines.AppendLine("\nadd_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")");
+ }
+
cmakeLists = cmakeLists.Replace("%Defines%", defines.ToString());
string plist = Utils.GetEmbeddedResource("Info.plist.template")