Skip to content

[CoreCLR] Automatically detach current thread from JNI #10316

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

simonrozsival
Copy link
Member

Fixes #10314

In #10198 I added code which attaches current thread to JNI (https://github.com/dotnet/android/pull/10198/files#diff-fc0414b3741163879db7993fd1fb42fa76e5305bb54c0e9478e077b3094e7aa7R42-R46). If this code is called from a thread pool thread, the thread won't be detached from JNI when exitting.

This PR adds the recommended steps to automatically detach the thread from JNI when exitting: https://developer.android.com/training/articles/perf-jni#threads

/cc @grendello @jonathanpeppers

Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

Is there a way to add a test for this?

Or did MAUI's tests crash on exit? So, we'd need to somehow run an extra test suite?

@jonpryor
Copy link
Contributor

What's odd is that I think we have a test for this? Maybe?

From the abort message in #10314:

7-21 15:25:22.624  1610  1610 F DEBUG   : Abort message: 'art/runtime/thread.cc:1223] Native thread exited without calling DetachCurrentThread: Thread[15,tid=4355,Native,Thread*=0x7f3c09434600,peer=0x12c89580,"Thread-234"]'

which suggests that if we:

  1. Create a new Thread
  2. Do some JNI work on that thread, and
  3. Exit the thread

then the assertion should be triggered, no?

We have tests that do that, e.g.:

[Test]
public void ConversionsAndThreadsAndInstanceMappingsOhMy ()
{
IntPtr lrefJliArray = JNIEnv.NewObjectArray<int> (new[]{1});
IntPtr grefJliArray = JNIEnv.NewGlobalRef (lrefJliArray);
JNIEnv.DeleteLocalRef (lrefJliArray);
Java.Lang.Object[] jarray = (Java.Lang.Object[])
JNIEnv.GetArray (grefJliArray, JniHandleOwnership.DoNotTransfer, typeof(Java.Lang.Object));
Exception ignore_t1 = null;
Exception ignore_t2 = null;
var t1 = new Thread (() => {
int[] output_array1 = new int[1];
for (int i = 0; i < 2000; ++i) {
Console.WriteLine ("# t1 iter: {0}", i);
try {
JNIEnv.CopyObjectArray (grefJliArray, output_array1);
} catch (Exception e) {
ignore_t1 = e;
break;
}
}
});
var t2 = new Thread (() => {
for (int i = 0; i < 2000; ++i) {
Console.WriteLine ("# t2 iter: {0}", i);
try {
JNIEnv.GetArray<int>(jarray);
} catch (Exception e) {
ignore_t2 = e;
break;
}
}
});
t1.Start ();
t2.Start ();
t1.Join ();
t2.Join ();
for (int i = 0; i < jarray.Length; ++i) {
jarray [i].Dispose ();
jarray [i] = null;
}
JNIEnv.DeleteGlobalRef (grefJliArray);
Assert.IsNull (ignore_t1, string.Format ("No exception should be thrown [t1]! Got: {0}", ignore_t1));
Assert.IsNull (ignore_t2, string.Format ("No exception should be thrown [t2]! Got: {0}", ignore_t2));
}

so why didn't we hit this before?

Are thread pool threads different from "normal" new System.Threading.Thread()?

Do we need to do "different" kinds of JNI calls on the created thread to trigger the assertion? It likely wouldn't be a bad idea to have a test that does:

var t = new Thread(() => {
    var list = new Java.Util.ArrayList();
    list.Add(new Java.Lang.String("a");
    list.Add(new Java.Lang.Integer(42);
});
t.Start();
t.Join();

and do a bit more than straight JNIEnv calls on the created thread.

The assert message, as-is, does not imply to me that we need to worry about app exit. (And that's ignoring the fact that "app exit" is a very nebulous concept on Android in the first place!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Running device tests for CoreCLR failing on maui
3 participants