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

[Microsoft.Android.Runtime.NativeAOT] Parse debug.mono.log #9824

Merged
merged 2 commits into from
Feb 24, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
using System.IO;
using System.Text;
using System.Runtime.InteropServices;

using Java.Interop;

namespace Microsoft.Android.Runtime;

struct DiagnosticSettings {

public bool LogJniLocalReferences;
private string? LrefPath;

public bool LogJniGlobalReferences;
private string? GrefPath;

private TextWriter? GrefLrefLog;


public TextWriter? GrefLog {
get {
if (!LogJniGlobalReferences) {
return null;
}
return ((LrefPath != null && LrefPath == GrefPath)
? GrefLrefLog ??= CreateWriter (LrefPath)
: null)
??
((GrefPath != null)
? CreateWriter (GrefPath)
: null)
??
new LogcatTextWriter (AndroidLogLevel.Debug, "NativeAot:GREF");
}
}

public TextWriter? LrefLog {
get {
if (!LogJniLocalReferences) {
return null;
}
return ((LrefPath != null && LrefPath == GrefPath)
? GrefLrefLog ??= CreateWriter (LrefPath)
: null)
??
((LrefPath != null)
? CreateWriter (LrefPath)
: null)
??
new LogcatTextWriter (AndroidLogLevel.Debug, "NativeAot:LREF");
}
}
Comment on lines +20 to +52
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read through these twice, as it seemed easy to have a typo. I think they are right.


TextWriter? CreateWriter (string path)
{
try {
return File.CreateText (path);
}
catch (Exception e) {
AndroidLog.Print (AndroidLogLevel.Error, "NativeAot", $"Failed to open log file `{path}`: {e}");
return null;
}
}

public void AddDebugDotnetLog ()
{
Span<byte> value = stackalloc byte [RuntimeNativeMethods.PROP_VALUE_MAX];
if (!RuntimeNativeMethods.TryGetSystemProperty ("debug.dotnet.log"u8, ref value)) {
return;
}
AddParse (value);
}

void AddParse (ReadOnlySpan<byte> value)
{
while (TryGetNextValue (ref value, out var v)) {
if (v.SequenceEqual ("lref"u8)) {
LogJniLocalReferences = true;
}
else if (v.StartsWith ("lref="u8)) {
LogJniLocalReferences = true;
var path = v.Slice ("lref=".Length);
LrefPath = Encoding.UTF8.GetString (path);
}
else if (v.SequenceEqual ("gref"u8)) {
LogJniGlobalReferences = true;
}
else if (v.StartsWith ("gref="u8)) {
LogJniGlobalReferences = true;
var path = v.Slice ("gref=".Length);
GrefPath = Encoding.UTF8.GetString (path);
}
else if (v.SequenceEqual ("all"u8)) {
LogJniLocalReferences = true;
LogJniGlobalReferences = true;
}
}

bool TryGetNextValue (ref ReadOnlySpan<byte> value, out ReadOnlySpan<byte> next)
{
if (value.Length == 0) {
next = default;
return false;
}
int c = value.IndexOf ((byte) ',');
if (c >= 0) {
next = value.Slice (0, c);
value = value.Slice (c + 1);
}
else {
next = value;
value = default;
}
return true;
}
}
}

static partial class RuntimeNativeMethods {

[LibraryImport ("c", EntryPoint="__system_property_get")]
static private partial int system_property_get (ReadOnlySpan<byte> name, Span<byte> value);

internal const int PROP_VALUE_MAX = 92;

internal static bool TryGetSystemProperty (ReadOnlySpan<byte> name, ref Span<byte> value)
{
int len = system_property_get (name, value);
if (len <= 0) {
return false;
}

value = value.Slice (0, len);
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Microsoft.Android.Runtime;

static class JavaInteropRuntime
static partial class JavaInteropRuntime
{
static JniRuntime? runtime;

Expand Down Expand Up @@ -34,14 +34,17 @@ static void JNI_OnUnload (IntPtr vm, IntPtr reserved)
static void init (IntPtr jnienv, IntPtr klass)
{
try {
var settings = new DiagnosticSettings ();
settings.AddDebugDotnetLog ();

var typeManager = new NativeAotTypeManager ();
var options = new NativeAotRuntimeOptions {
EnvironmentPointer = jnienv,
TypeManager = typeManager,
ValueManager = new NativeAotValueManager (typeManager),
UseMarshalMemberBuilder = false,
JniGlobalReferenceLogWriter = new LogcatTextWriter (AndroidLogLevel.Debug, "NativeAot:GREF"),
JniLocalReferenceLogWriter = new LogcatTextWriter (AndroidLogLevel.Debug, "NativeAot:LREF"),
JniGlobalReferenceLogWriter = settings.GrefLog,
JniLocalReferenceLogWriter = settings.LrefLog,
};
runtime = options.CreateJreVM ();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<SignAssembly>true</SignAssembly>
<OutputPath>$(_MonoAndroidNETDefaultOutDir)</OutputPath>
<RootNamespace>Microsoft.Android.Runtime</RootNamespace>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading