-
Notifications
You must be signed in to change notification settings - Fork 561
[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
Conversation
There was a problem hiding this 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?
|
What's odd is that I think we have a test for this? Maybe? From the abort message in #10314: which suggests that if we:
then the assertion should be triggered, no? We have tests that do that, e.g.: android/tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/JnienvTest.cs Lines 329 to 380 in 510fc08
so why didn't we hit this before? Are thread pool threads different from "normal" 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 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!) |
|
@jonpryor I think the situation here is a bit different, at least from looking at the crash stack trace attached to #10314 (comment) This is 100% native + ART. @simonrozsival might be onto something with this PR (btw, why was it closed?) the thread mentioned in the abort message (PID 4651) is created to run a test: If the GC bridge kicks in while the test is running and on the same thread that crashes, this would explain the error. Our test assumes that calling a JNI method actually attaches the thread to JNI, which might not be the case. |
I was not able to finish the work on the PR and fully test it, so I closed it for the time being. We can definitely revisit the PR.
I don't know if this could be caused by the GC itself (GC has a background thread and the GC bridge has its own separate background thread, both of which are attached to JNI but both should live thoughout app's lifetime). The changes to the My hypothesis was that when this code is reached on a threadpool thread then the TP thread is attached to JNI and it is likely that this thread will be exitted at some point. This would cause the app to crash because we don't have the automatic detach machanism implemented. I wasn't able to reproduce the crash locally before I left on vacation, so I abandoned this attempt at that time. |
|
@simonrozsival does threadpool actually attach threads to JNI? If I remember correctly, both MonoVM and CoreCLR use the same managed threadpool implementation? If it is indeed true, then the code crashing on CoreCLR but working on MonoVM would actually be a runtime issue. On MonoVM we get called back whenever any managed thread is created/destroyed, so we can attach/detach accordingly. On CoreCLR we don't have this opportunity, so it is on the runtime to do the right thing. I used GC bridge as an example of what might occur, it's hard to tell from the stack trace that this is really the case - as you say, it can be anything that creates the thread, attaches it, but then fails to detach. If it's a managed thread, then it will exit only after the workload running it it finishes (I hope that this is the case), so there's still the chance to do the right thing there, a chance that maybe is missed for some reason? TBH, I would love if CoreCLR called us back the same way MonoVM does on any thread creation/distruction, so that we can control things like JNI/JVM thread attachment/detachment. |
If at some point the |
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