Skip to content

[One .NET] fix libmono-profiler-aot.so recording #6680

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

Merged
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
2 changes: 1 addition & 1 deletion build-tools/automation/azure-pipelines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ variables:
- name: RunAllTests
value: $[or(eq(variables['XA.RunAllTests'], true), eq(variables['IsMonoBranch'], true))]
- name: DotNetNUnitCategories
value: '& TestCategory != DotNetIgnore & TestCategory != HybridAOT & TestCategory != ProfiledAOT & TestCategory != MkBundle & TestCategory != MonoSymbolicate & TestCategory != PackagesConfig & TestCategory != StaticProject & TestCategory != Debugger & TestCategory != SystemApplication'
value: '& TestCategory != DotNetIgnore & TestCategory != HybridAOT & TestCategory != MkBundle & TestCategory != MonoSymbolicate & TestCategory != PackagesConfig & TestCategory != StaticProject & TestCategory != Debugger & TestCategory != SystemApplication'
- ${{ if eq(variables['Build.DefinitionName'], 'Xamarin.Android-Private') }}:
- group: AzureDevOps-Artifact-Feeds-Pats
- group: DotNet-MSRC-Storage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
<Output PropertyName="_LdFlags" TaskParameter="LdFlags" />
<Output ItemName="_MonoAOTAssemblies" TaskParameter="ResolvedAssemblies" />
</GetAotAssemblies>
<ItemGroup Condition=" '$(AndroidExtraAotOptions)' != '' ">
<_MonoAOTAssemblies Update="@(_MonoAOTAssemblies)" ProcessArguments="$(AndroidExtraAotOptions)" />
</ItemGroup>
<PropertyGroup>
<_MonoAOTCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier', '$(RuntimeIdentifier)'))</_MonoAOTCompilerPath>
<_LLVMPath Condition=" '$(EnableLLVM)' == 'true' ">$([System.IO.Path]::GetDirectoryName ('$(_MonoAOTCompilerPath)'))</_LLVMPath>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ public void TearDown ()
Directory.Delete (SdkWithSpacesPath, recursive: true);
}

void AssertProfiledAotBuildMessages(ProjectBuilder b)
{
string filename = Builder.UseDotNet ? "dotnet" : "startup";
StringAssertEx.ContainsRegex (@$"Using profile data file.*{filename}\.aotprofile", b.LastBuildOutput, "Should use default AOT profile", RegexOptions.IgnoreCase);
StringAssertEx.ContainsRegex (@$"Method.*emitted at", b.LastBuildOutput, "Should contain verbose AOT compiler output", RegexOptions.IgnoreCase);
}

[Test, Category ("SmokeTests"), Category ("ProfiledAOT")]
public void BuildBasicApplicationReleaseProfiledAot ()
{
Expand All @@ -58,11 +65,9 @@ public void BuildBasicApplicationReleaseProfiledAot ()
AndroidEnableProfiledAot = true,
};
proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidExtraAotOptions", "--verbose");
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
StringAssertEx.ContainsRegex (@"\[aot-compiler stdout\] Using profile data file.*build.Xamarin.Android.startup\.aotprofile", b.LastBuildOutput, "Should use default AOT profile", RegexOptions.IgnoreCase);
StringAssertEx.ContainsRegex (@"\[aot-compiler stdout\] Method.*emitted at", b.LastBuildOutput, "Should contain verbose AOT compiler output", RegexOptions.IgnoreCase);
}
using var b = CreateApkBuilder ();
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
AssertProfiledAotBuildMessages (b);
}

[Test, Category ("SmokeTests"), Category ("ProfiledAOT")]
Expand All @@ -81,11 +86,9 @@ public void BuildBasicApplicationReleaseWithCustomAotProfile ()
}
proj.OtherBuildItems.Add (new BuildItem ("AndroidAotProfile", "custom.aotprofile") { BinaryContent = () => custom_aot_profile });

using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
StringAssertEx.ContainsRegex (@"\[aot-compiler stdout\] Using profile data file.*custom\.aotprofile", b.LastBuildOutput, "Should use custom AOT profile", RegexOptions.IgnoreCase);
StringAssertEx.ContainsRegex (@"\[aot-compiler stdout\] Method.*emitted at", b.LastBuildOutput, "Should contain verbose AOT compiler output", RegexOptions.IgnoreCase);
}
using var b = CreateApkBuilder ();
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
AssertProfiledAotBuildMessages (b);
}

[Test, Category ("ProfiledAOT")]
Expand All @@ -96,10 +99,10 @@ public void BuildBasicApplicationReleaseProfiledAotWithoutDefaultProfile ()
AndroidEnableProfiledAot = true,
};
proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidUseDefaultAotProfile", "false");
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
StringAssertEx.DoesNotContainRegex (@"\[aot-compiler stdout\] Using profile data file.*build.Xamarin.Android.startup.*\.aotprofile", b.LastBuildOutput, "Should not use default AOT profile", RegexOptions.IgnoreCase);
}
using var b = CreateApkBuilder ();
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
string filename = Builder.UseDotNet ? "dotnet" : "startup";
StringAssertEx.DoesNotContainRegex (@$"Using profile data file.*{filename}\.aotprofile", b.LastBuildOutput, "Should not use default AOT profile", RegexOptions.IgnoreCase);
}

static object [] AotChecks () => new object [] {
Expand Down
1 change: 1 addition & 0 deletions src/monodroid/jni/monodroid-glue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1686,6 +1686,7 @@ MonodroidRuntime::set_profile_options ()
.append (AOT_EXT);

value
.append (",")
.append (OUTPUT_ARG)
.append (output_path.get (), output_path.length ());
}
Expand Down
41 changes: 40 additions & 1 deletion tests/MSBuildDeviceIntegration/Tests/AotProfileTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using NUnit.Framework;
using NUnit.Framework;
using System;
using System.IO;
using System.Net;
using Xamarin.ProjectTools;

namespace Xamarin.Android.Build.Tests
Expand All @@ -26,6 +27,7 @@ public void BuildBasicApplicationAndAotProfileIt ()
IsRelease = true,
};
proj.SetAndroidSupportedAbis ("armeabi-v7a", "x86");
AddDotNetProfilerNativeLibraries (proj);
var port = 9000 + new Random ().Next (1000);
proj.SetProperty ("AndroidAotProfilerPort", port.ToString ());
proj.AndroidManifest = string.Format (PermissionManifest, proj.PackageName);
Expand All @@ -35,10 +37,47 @@ public void BuildBasicApplicationAndAotProfileIt ()
WaitForAppBuiltForOlderAndroidWarning (proj.PackageName, Path.Combine (Root, b.ProjectDirectory, "oldsdk-logcat.log"));
System.Threading.Thread.Sleep (5000);
b.BuildLogFile = "build2.log";

// Need execute permission
if (Builder.UseDotNet && !IsWindows) {
var aprofutil = Path.Combine (Root, b.ProjectDirectory, "aprofutil");
RunProcess ("chmod", $"u+x {aprofutil}");
}

Assert.IsTrue (b.RunTarget (proj, "FinishAotProfiling", doNotCleanupOnUpdate: true), "Run of FinishAotProfiling should have succeeded.");
var customProfile = Path.Combine (Root, projDirectory, "custom.aprof");
FileAssert.Exists (customProfile);
}
}

void AddDotNetProfilerNativeLibraries (XamarinAndroidApplicationProject proj)
{
// TODO: only needed in .NET 6+
// See https://github.com/dotnet/runtime/issues/56989
if (!Builder.UseDotNet)
return;

// Files are built from dotnet/runtime & stored at:
const string github = "https://github.com/jonathanpeppers/android-profiled-aot";

proj.Sources.Add (new BuildItem ("None", "aprofutil") {
WebContent = $"{github}/raw/main/binaries/aprofutil"
});
proj.Sources.Add (new BuildItem ("None", "aprofutil.exe") {
WebContent = $"{github}/raw/main/binaries/aprofutil.exe"
});
proj.Sources.Add (new BuildItem ("None", "Mono.Profiler.Log.dll") {
WebContent = $"{github}/raw/main/binaries/Mono.Profiler.Log.dll"
});
proj.SetProperty ("AProfUtilToolPath", "$(MSBuildThisFileDirectory)");

foreach (var rid in proj.GetProperty (KnownProperties.RuntimeIdentifiers).Split (';')) {
//NOTE: each rid has the same file name, so using WebClient directly
var bytes = new WebClient ().DownloadData ($"{github}/raw/main/binaries/{rid}/libmono-profiler-aot.so");
proj.Sources.Add (new AndroidItem.AndroidNativeLibrary ($"{rid}\\libmono-profiler-aot.so") {
BinaryContent = () => bytes,
});
}
}
}
}