Skip to content

Commit e41a250

Browse files
authored
Add diagnostic support into sample app and AppBuilders on Mono. (#53361)
1 parent fea7ff2 commit e41a250

File tree

10 files changed

+144
-16
lines changed

10 files changed

+144
-16
lines changed

src/mono/sample/Android/AndroidSampleApp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@
7979
Assemblies="@(BundleAssemblies)"
8080
MainLibraryFileName="$(AssemblyName).dll"
8181
StripDebugSymbols="$(StripDebugSymbols)"
82+
RuntimeComponents="$(RuntimeComponents)"
83+
DiagnosticPorts="$(DiagnosticPorts)"
8284
OutputDir="$(ApkDir)"
8385
AppDir="$(PublishDir)">
8486
<Output TaskParameter="ApkBundlePath" PropertyName="ApkBundlePath" />

src/mono/sample/Android/Makefile

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ DOTNET := ../../../../dotnet.sh
44
USE_LLVM=true
55
AOT=false
66
DEPLOY_AND_RUN?=true
7+
RUNTIME_COMPONENTS=diagnostics_tracing
8+
9+
#If DIAGNOSTIC_PORTS is enabled, RUNTIME_COMPONENTS must also be enabled.
10+
#If RUNTIME_COMPONENTS is enabled, DIAGNOSTIC_PORTS is optional.
11+
#If RUNTIME_COMPONENTS is enabled, DIAGNOSTIC_PORTS is disabled, use DOTNET_DiagnosticPorts when launching application to enable diagnostics.
12+
#RUNTIME_COMPONENTS=diagnostics_tracing
13+
#DIAGNOSTIC_PORTS=10.0.2.2:9000,nosuspend
14+
#DIAGNOSTIC_PORTS=10.0.2.2:9000,suspend
15+
#DIAGNOSTIC_PORTS=$(DOTNET_DiagnosticPorts)
16+
717

818
all: runtimepack run
919

@@ -18,7 +28,9 @@ run:
1828
/p:DeployAndRun=$(DEPLOY_AND_RUN) \
1929
/p:ForceAOT=$(AOT) \
2030
/p:UseLLVM=$(USE_LLVM) \
21-
/p:RunActivity=false
31+
/p:RunActivity=false \
32+
'/p:RuntimeComponents="$(RUNTIME_COMPONENTS)"' \
33+
'/p:DiagnosticPorts="$(DIAGNOSTIC_PORTS)"'
2234

2335
clean:
2436
rm -rf ../../../../artifacts/bin/AndroidSampleApp

src/mono/sample/iOS/Makefile

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ DOTNET := ../../../../dotnet.sh
44
USE_LLVM=true
55
AOT=false
66

7+
#If DIAGNOSTIC_PORTS is enabled, RUNTIME_COMPONENTS must also be enabled.
8+
#If RUNTIME_COMPONENTS is enabled, DIAGNOSTIC_PORTS is optional.
9+
#If RUNTIME_COMPONENTS is enabled, DIAGNOSTIC_PORTS is disabled, use DOTNET_DiagnosticPorts when launching application to enable diagnostics.
10+
#RUNTIME_COMPONENTS=diagnostics_tracing
11+
#DIAGNOSTIC_PORTS=127.0.0.1:9000,nosuspend
12+
#DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend
13+
#DIAGNOSTIC_PORTS=$(DOTNET_DiagnosticPorts)
14+
715
all: runtimepack run
816

917
TOOLS_DIR=../../../tasks
@@ -15,24 +23,51 @@ runtimepack:
1523
../../../../build.sh Mono+Libs -os iOSSimulator -arch $(MONO_ARCH) -c $(MONO_CONFIG)
1624

1725
run: clean appbuilder
18-
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) \
19-
/p:UseLLVM=$(USE_LLVM) /p:ForceAOT=$(AOT)
26+
$(DOTNET) publish \
27+
-c $(MONO_CONFIG) \
28+
/p:TargetArchitecture=$(MONO_ARCH) \
29+
/p:UseLLVM=$(USE_LLVM) \
30+
/p:ForceAOT=$(AOT) \
31+
'/p:RuntimeComponents="$(RUNTIME_COMPONENTS)"' \
32+
'/p:DiagnosticPorts="$(DIAGNOSTIC_PORTS)"'
2033

2134
run-sim: clean appbuilder
22-
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=iOSSimulator /p:TargetArchitecture=$(MONO_ARCH) \
23-
/p:UseLLVM=$(USE_LLVM) /p:ForceAOT=$(AOT)
35+
$(DOTNET) publish \
36+
-c $(MONO_CONFIG) \
37+
/p:TargetOS=iOSSimulator \
38+
/p:TargetArchitecture=$(MONO_ARCH) \
39+
/p:UseLLVM=$(USE_LLVM) \
40+
/p:ForceAOT=$(AOT) \
41+
'/p:RuntimeComponents="$(RUNTIME_COMPONENTS)"' \
42+
'/p:DiagnosticPorts="$(DIAGNOSTIC_PORTS)"'
2443

2544
run-catalyst:
26-
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=MacCatalyst /p:TargetArchitecture=$(MONO_ARCH) \
27-
/p:UseLLVM=False /p:ForceAOT=False
45+
$(DOTNET) publish \
46+
-c $(MONO_CONFIG) \
47+
/p:TargetOS=MacCatalyst \
48+
/p:TargetArchitecture=$(MONO_ARCH) \
49+
/p:UseLLVM=False \
50+
/p:ForceAOT=False
2851

2952
run-sim-interp: clean appbuilder
30-
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=iOSSimulator /p:TargetArchitecture=$(MONO_ARCH) \
31-
/p:UseLLVM=$(USE_LLVM) /p:ForceAOT=$(AOT) /p:MonoForceInterpreter=true
53+
$(DOTNET) publish \
54+
-c $(MONO_CONFIG) \
55+
/p:TargetOS=iOSSimulator \
56+
/p:TargetArchitecture=$(MONO_ARCH) \
57+
/p:UseLLVM=$(USE_LLVM) \
58+
/p:ForceAOT=$(AOT) \
59+
/p:MonoForceInterpreter=true \
60+
'/p:RuntimeComponents="$(RUNTIME_COMPONENTS)"' \
61+
'/p:DiagnosticPorts="$(DIAGNOSTIC_PORTS)"'
3262

3363
run-catalyst-interp:
34-
$(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=MacCatalyst /p:TargetArchitecture=$(MONO_ARCH) \
35-
/p:UseLLVM=False /p:ForceAOT=False /p:MonoForceInterpreter=true
64+
$(DOTNET) publish \
65+
-c $(MONO_CONFIG) \
66+
/p:TargetOS=MacCatalyst \
67+
/p:TargetArchitecture=$(MONO_ARCH) \
68+
/p:UseLLVM=False \
69+
/p:ForceAOT=False \
70+
/p:MonoForceInterpreter=true
3671

3772
clean:
3873
rm -rf bin

src/mono/sample/iOS/Program.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@
8484
Optimized="$(Optimized)"
8585
ForceAOT="$(ForceAOT)"
8686
ForceInterpreter="$(MonoForceInterpreter)"
87+
RuntimeComponents="$(RuntimeComponents)"
88+
DiagnosticPorts="$(DiagnosticPorts)"
8789
AppDir="$(MSBuildThisFileDirectory)$(PublishDir)">
8890
<Output TaskParameter="AppBundlePath" PropertyName="AppBundlePath" />
8991
<Output TaskParameter="XcodeProjectPath" PropertyName="XcodeProjectPath" />

src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public class AndroidAppBuilderTask : Task
4343
/// </summary>
4444
public string? RuntimeComponents { get; set; } = ""!;
4545

46+
/// <summary>
47+
/// Diagnostic ports configuration string
48+
/// </summary>
49+
public string? DiagnosticPorts { get; set; } = ""!;
50+
4651
[Required]
4752
public string RuntimeIdentifier { get; set; } = ""!;
4853

@@ -102,6 +107,7 @@ public override bool Execute()
102107
apkBuilder.ForceAOT = ForceAOT;
103108
apkBuilder.StaticLinkedRuntime = StaticLinkedRuntime;
104109
apkBuilder.RuntimeComponents = RuntimeComponents;
110+
apkBuilder.DiagnosticPorts = DiagnosticPorts;
105111
apkBuilder.Assemblies = Assemblies;
106112
(ApkBundlePath, ApkPackageId) = apkBuilder.BuildApk(abi, MainLibraryFileName, MonoRuntimeHeaders);
107113

src/tasks/AndroidAppBuilder/ApkBuilder.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class ApkBuilder
2828
public bool EnableRuntimeLogging { get; set; }
2929
public bool StaticLinkedRuntime { get; set; }
3030
public string? RuntimeComponents { get; set; }
31+
public string? DiagnosticPorts { get; set; }
3132
public ITaskItem[] Assemblies { get; set; } = Array.Empty<ITaskItem>();
3233

3334
public (string apk, string packageId) BuildApk(
@@ -79,6 +80,21 @@ public class ApkBuilder
7980
throw new InvalidOperationException("Interpreter and AOT cannot be enabled at the same time");
8081
}
8182

83+
if (!string.IsNullOrEmpty(DiagnosticPorts))
84+
{
85+
bool validDiagnosticsConfig = false;
86+
87+
if (string.IsNullOrEmpty(RuntimeComponents))
88+
validDiagnosticsConfig = false;
89+
else if (RuntimeComponents.Equals("*", StringComparison.OrdinalIgnoreCase))
90+
validDiagnosticsConfig = true;
91+
else if (RuntimeComponents.Contains("diagnostics_tracing", StringComparison.OrdinalIgnoreCase))
92+
validDiagnosticsConfig = true;
93+
94+
if (!validDiagnosticsConfig)
95+
throw new ArgumentException("Using DiagnosticPorts require diagnostics_tracing runtime component.");
96+
}
97+
8298
// Try to get the latest build-tools version if not specified
8399
if (string.IsNullOrEmpty(BuildToolsVersion))
84100
BuildToolsVersion = GetLatestBuildTools(AndroidSdk);
@@ -268,6 +284,11 @@ public class ApkBuilder
268284
defines = "add_definitions(-DFORCE_AOT=1)";
269285
}
270286

287+
if (!string.IsNullOrEmpty(DiagnosticPorts))
288+
{
289+
defines += "\nadd_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")";
290+
}
291+
271292
cmakeLists = cmakeLists.Replace("%Defines%", defines);
272293

273294
File.WriteAllText(Path.Combine(OutputDir, "CMakeLists.txt"), cmakeLists);

src/tasks/AndroidAppBuilder/Templates/monodroid.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,20 @@ cleanup_runtime_config (MonovmRuntimeConfigArguments *args, void *user_data)
205205
int
206206
mono_droid_runtime_init (const char* executable, int managed_argc, char* managed_argv[])
207207
{
208+
// NOTE: these options can be set via command line args for adb or xharness, see AndroidSampleApp.csproj
209+
208210
// uncomment for debug output:
209211
//
210212
//setenv ("XUNIT_VERBOSE", "true", true);
211213
//setenv ("MONO_LOG_LEVEL", "debug", true);
212214
//setenv ("MONO_LOG_MASK", "all", true);
213-
// NOTE: these options can be set via command line args for adb or xharness, see AndroidSampleApp.csproj
215+
216+
// build using DiagnosticPorts property in AndroidAppBuilder
217+
// or set DOTNET_DiagnosticPorts env via adb, xharness when undefined.
218+
// NOTE, using DOTNET_DiagnosticPorts requires app build using AndroidAppBuilder and RuntimeComponents=diagnostics_tracing
219+
#ifdef DIAGNOSTIC_PORTS
220+
setenv ("DOTNET_DiagnosticPorts", DIAGNOSTIC_PORTS, true);
221+
#endif
214222

215223
bool wait_for_debugger = false;
216224
chdir (bundle_path);
@@ -266,14 +274,18 @@ mono_droid_runtime_init (const char* executable, int managed_argc, char* managed
266274
mono_jit_set_aot_mode(MONO_AOT_MODE_FULL);
267275
#endif
268276

269-
mono_jit_init_version ("dotnet.android", "mobile");
277+
MonoDomain *domain = mono_jit_init_version ("dotnet.android", "mobile");
278+
assert (domain);
270279

271280
MonoAssembly *assembly = mono_droid_load_assembly (executable, NULL);
272281
assert (assembly);
273-
LOG_INFO ("Executable: %s", executable);
274282

275-
int res = mono_jit_exec (mono_domain_get (), assembly, managed_argc, managed_argv);
283+
LOG_INFO ("Executable: %s", executable);
284+
int res = mono_jit_exec (domain, assembly, managed_argc, managed_argv);
276285
LOG_INFO ("Exit code: %d.", res);
286+
287+
mono_jit_cleanup (domain);
288+
277289
return res;
278290
}
279291

src/tasks/AppleAppBuilder/AppleAppBuilder.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ public string TargetOS
131131
/// </summary>
132132
public string? RuntimeComponents { get; set; } = ""!;
133133

134+
/// <summary>
135+
/// Diagnostic ports configuration string
136+
/// </summary>
137+
public string? DiagnosticPorts { get; set; } = ""!;
138+
134139
/// <summary>
135140
/// Forces the runtime to use the invariant mode
136141
/// </summary>
@@ -198,10 +203,26 @@ public override bool Execute()
198203
throw new InvalidOperationException("Interpreter and AOT cannot be enabled at the same time");
199204
}
200205

206+
if (!string.IsNullOrEmpty(DiagnosticPorts))
207+
{
208+
bool validDiagnosticsConfig = false;
209+
210+
if (string.IsNullOrEmpty(RuntimeComponents))
211+
validDiagnosticsConfig = false;
212+
else if (RuntimeComponents.Equals("*", StringComparison.OrdinalIgnoreCase))
213+
validDiagnosticsConfig = true;
214+
else if (RuntimeComponents.Contains("diagnostics_tracing", StringComparison.OrdinalIgnoreCase))
215+
validDiagnosticsConfig = true;
216+
217+
if (!validDiagnosticsConfig)
218+
throw new ArgumentException("Using DiagnosticPorts require diagnostics_tracing runtime component.");
219+
}
220+
201221
if (GenerateXcodeProject)
202222
{
203223
Xcode generator = new Xcode(TargetOS, Arch);
204224
generator.EnableRuntimeLogging = EnableRuntimeLogging;
225+
generator.DiagnosticPorts = DiagnosticPorts;
205226

206227
XcodeProjectPath = generator.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles,
207228
AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, Optimized, RuntimeComponents, NativeMainSource);

src/tasks/AppleAppBuilder/Templates/runtime.m

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,13 @@
231231
setenv ("MONO_LOG_MASK", "all", TRUE);
232232
#endif
233233

234+
// build using DiagnosticPorts property in AppleAppBuilder
235+
// or set DOTNET_DiagnosticPorts env via mlaunch, xharness when undefined.
236+
// NOTE, using DOTNET_DiagnosticPorts requires app build using AppleAppBuilder and RuntimeComponents=diagnostics_tracing
237+
#ifdef DIAGNOSTIC_PORTS
238+
setenv ("DOTNET_DiagnosticPorts", DIAGNOSTIC_PORTS, true);
239+
#endif
240+
234241
id args_array = [[NSProcessInfo processInfo] arguments];
235242
assert ([args_array count] <= 128);
236243
const char *managed_argv [128];
@@ -308,7 +315,9 @@
308315
char* options[] = { "--debugger-agent=transport=dt_socket,server=y,address=0.0.0.0:55555" };
309316
mono_jit_parse_options (1, options);
310317
}
311-
mono_jit_init_version ("dotnet.ios", "mobile");
318+
319+
MonoDomain *domain = mono_jit_init_version ("dotnet.ios", "mobile");
320+
assert (domain);
312321

313322
#if !FORCE_INTERPRETER && (!TARGET_OS_SIMULATOR || FORCE_AOT)
314323
// device runtimes are configured to use lazy gc thread creation
@@ -326,5 +335,7 @@
326335
// Print this so apps parsing logs can detect when we exited
327336
os_log_info (OS_LOG_DEFAULT, "Exit code: %d.", res);
328337

338+
mono_jit_cleanup (domain);
339+
329340
exit (res);
330341
}

src/tasks/AppleAppBuilder/Xcode.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public Xcode(string target, string arch)
4141
}
4242

4343
public bool EnableRuntimeLogging { get; set; }
44+
public string? DiagnosticPorts { get; set; } = ""!;
4445

4546
public string GenerateXCode(
4647
string projectName,
@@ -212,6 +213,11 @@ public string GenerateXCode(
212213
defines.AppendLine("add_definitions(-DENABLE_RUNTIME_LOGGING=1)");
213214
}
214215

216+
if (!string.IsNullOrEmpty(DiagnosticPorts))
217+
{
218+
defines.AppendLine("\nadd_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")");
219+
}
220+
215221
cmakeLists = cmakeLists.Replace("%Defines%", defines.ToString());
216222

217223
string plist = Utils.GetEmbeddedResource("Info.plist.template")

0 commit comments

Comments
 (0)