Some comments below
On 07/04/2021 8:21, Matthias Bläsing wrote:
Hi Antonio,
Am Dienstag, den 06.04.2021, 23:24 +0200 schrieb antonio:
[...]
Here is the stack trace for it (from hs_err_pid*):
Stack: [0x00007fa41ce47000,0x00007fa41d646000], sp=0x00007fa41d6449c0, free
space=8182k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted,
Vv=VM code, C=native code)
V [libjvm.so+0x91203a] jni_CallStaticBooleanMethodV+0x7a
C [libjfxwebkit.so+0x5fd155] JNIEnv_::CallStaticBooleanMethod(_jclass*,
_jmethodID*, ...)+0x85
C [libjfxwebkit.so+0x2a0d82a] WTF::FileSystemImpl::makeAllDirectories(WTF::String
const&)+0xda
It seems "makeAllDirectories"
(https://github.com/openjdk/jfx/blob/e0ce73a3c8d82d3274bd10799b530f397a90ba60/modules/javafx.web/src/main/native/Source/WTF/wtf/java/FileSystemJava.cpp#L143)
being invoked by a native thread does not use jvm->AttachCurrentThread.
We'll have unexpected behaviour.
This is a bug in libjfxwebkit that you may want to report.
C [libjfxwebkit.so+0x553707]
WebCore::StorageSyncManager::fullDatabaseFilename(WTF::String const&)+0x27
C [libjfxwebkit.so+0x54e83a]
WebKit::StorageAreaSync::openDatabase(WebKit::StorageAreaSync::OpenDatabaseParamType)+0x3a
C [libjfxwebkit.so+0x54f8a9] WebKit::StorageAreaSync::performImport()+0x29
C [libjfxwebkit.so+0x553f04] WebCore::StorageThread::threadEntryPoint()+0xb4
C [libjfxwebkit.so+0x29aa793]
WTF::Thread::entryPoint(WTF::Thread::NewThreadContext*)+0x63
C [libjfxwebkit.so+0x2a1253d] WTF::wtfThreadEntryPoint(void*)+0xd
There is no native frame and thus even if the thread itself would be
attached to the JVM as suggested in your second email, it would still
be missing a context to find that invoking java method and its class
loader.
What people usually do when using JNI is to create global references to
"jclass" and then reuse these global references in different threads.
These are thread safe and avoid being finding classes and methods all
the time.
a) On the JNI_OnLoad method (when the library is loaded) people do a
"FindClass" as usual, and then create a new global reference to the
jclass for future use in different threads, and store it in a global C
variable. Could be something like:
static jclass MyWhateverClass = NULL;
...
JNI_OnLoad(...) {
// Find the class in OnLoad
jclass clazz = env->FindClass(...);
// And keep a NewGlobalRef for future use...
MyWhateverClass = env->NewGlobalRef(clazz);
...
b) In the native thread people call jvm->AttachCurrentThread (mandatory)
and can then use the MyWhateverClass without invoking "FindClass" again.
These "jclass" allocated with NewGlobalRef are thread safe, and can be
used by different native threads (invoking AttachCurrentThread first)
without problems.
People usually cache also "jmethodID"s for future use, so they don't
have to lookup the methods on each call. These "jmethodID" are thread
safe by default, so there's no need to create a NewGlobalRef for them.
For details on what JNI stuff is or is not thread safe [1] gives a nice
summary.
So to summarize, I'm afraid they'll need to modify the code like so:
a) Use AttachCurrentThread in native method invocations (they may be
doing it elsewere, but probably not in the stack trace you're sending).
b) Cache the jclass(es?) they're using in native threads, by allocating
it(them?) in JNI_OnLoad using NewGlobalRef.
c) Use these cached jclass(es?) in the methods invoked by native calls.
Note that even if the bug reveals itself in NetBeans, it may happen
anywhere else.
Kind regards,
Antonio
[1]
https://latkin.org/blog/2016/02/01/jni-object-lifetimes-quick-reference/
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists