[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-openjfx-dev
Subject:    Re: JDK-8242361: Web View crash with data urls: reproducer with named module
From:       Matthias =?ISO-8859-1?Q?Bl=E4sing?= <mblaesing () doppel-helix ! eu>
Date:       2020-11-22 15:56:14
Message-ID: cd92fec9426ea20361f79452c78b89bf6c1fa3f2.camel () doppel-helix ! eu
[Download RAW message or body]

Hi again,

I experimented some more and I think this:

https://github.com/matthiasblaesing/reproduce-openjfx-crash2

shows, that the problem also exists when used from named modules. The
above sample can be run by:

- clone the referenced sources
- build the project with "mvn package"
- run it with mvn -Dexec.args="-classpath %classpath \
eu.doppel_helix.dev.jdk.reproducecrash.TestBrowser" -Dexec.executable=java \
org.codehaus.mojo:exec-maven-plugin:3.0.0:exec

I get an instant segfault on Ubuntu with OpenJDK 11.0.9.

From my interpretation this is caused by the behaviour of FindClass.
Quote from the docs of JDK 11:

======================================================================

Since JDK 1.2, the Java security model allows non-system classes to
load and call native methods. FindClass locates the class loader
associated with the current native method; that is, the class loader of
the class that declared the native method. If the native method belongs
to a system class, no class loader will be involved. Otherwise, the
proper class loader will be invoked to load and link the named class.

Since JDK 1.2, when FindClass is called through the Invocation
Interface, there is no current native method or its associated class
loader. In that case, the result of ClassLoader.getSystemClassLoader is
used. This is the class loader the virtual machine creates for
applications, and is able to locate classes listed in the
java.class.path property.

======================================================================

My take on this is, that in the common case OpenJFX hits the first
assumption. Classes are loaded with the classloader of the native
method, which should be able to load the necessary classes. In the case
where Webkit calls back into the JVM, the second paragraph becomes
important. OpenJFX is not loaded from the system class loader and
loading of MainThread class fails.

Based on this and my observation that isMainThread is successfully
called multiple time before the crash, I added this hack to the last
tag of OpenJFX 13 and rebuild:

--- a/modules/javafx.web/src/main/native/Source/WTF/wtf/java/MainThreadJava.cpp
+++ b/modules/javafx.web/src/main/native/Source/WTF/wtf/java/MainThreadJava.cpp
@@ -30,20 +30,21 @@
 #include <wtf/MainThread.h>
 
 namespace WTF {
+static JGClass jMainThreadCls2;
+
 void scheduleDispatchFunctionsOnMainThread()
 {
     AttachThreadAsNonDaemonToJavaEnv autoAttach;
     JNIEnv* env = autoAttach.env();
-    static JGClass jMainThreadCls(env->FindClass("com/sun/webkit/MainThread"));
 
     static jmethodID mid = env->GetStaticMethodID(
-            jMainThreadCls,
+            jMainThreadCls2,
             "fwkScheduleDispatchFunctions",
             "()V");
 
     ASSERT(mid);
 
-    env->CallStaticVoidMethod(jMainThreadCls, mid);
+    env->CallStaticVoidMethod(jMainThreadCls2, mid);
     WTF::CheckAndClearException(env);
 }
 
@@ -61,7 +62,7 @@
     AttachThreadAsNonDaemonToJavaEnv autoAttach;
     JNIEnv* env = autoAttach.env();
     static JGClass jMainThreadCls(env->FindClass("com/sun/webkit/MainThread"));
-
+    jMainThreadCls2 = jMainThreadCls;
     static jmethodID mid = env->GetStaticMethodID(
             jMainThreadCls,
             "fwkIsMainThread",


The idea is, that I retain the reference to the class and use that in
scheduleDispatchFunctionsOnMainThread.

I'm sure, that that is not the right approach, but it works and proves,
that the class is accessible.

Greetings

Matthias


Am Samstag, den 21.11.2020, 22:42 +0100 schrieb Matthias Bläsing:
Hi,

I found JDK-8242361, because I observed a segfault when running a web
application of medium complexity in a WebView, that was embedded in
NetBeans.

Before you say it: NetBeans loads the openjfx jars via the classpath.
I'm aware that OpenJFX should be loaded as a named module, but that is
far from trivial to realize inside the environment, so at this point in
time I'd like to try to fix the problem at hand.

I managed to get a core dump from the crash and running it through gdb
with debug symbols I get:

============================================================

#0  __GI_raise (sig=sig@entry=6) at
../sysdeps/unix/sysv/linux/raise.c:49
#1  0x00007f93c40e5864 in __GI_abort () at abort.c:79
#2  0x00007f93c30603e7 in os::abort(bool, void*, void const*)
(dump_core=<optimized out>, siginfo=<optimized out>, context=<optimized
out>) at ./src/hotspot/os/linux/os_linux.cpp:1503
#3  0x00007f93c3c58798 in VMError::report_and_die(int, char const*,
char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*,
char const*, int, unsigned long)
    (id=<optimized out>, message=message@entry=0x0,
detail_fmt=<optimized out>,
detail_args=detail_args@entry=0x7f9189ffe368,
thread=thread@entry=0x7f925c314000, pc=pc@entry=0x7f93c3348804
<AccessInternal::PostRuntimeDispatch<G1BarrierSet::AccessBarrier<109784
4ul, G1BarrierSet>, (AccessInternal::BarrierType)2,
1097844ul>::oop_access_barrier(void*)+4> "H\213\a\303\017\037\204",
siginfo=0x7f9189ffe6f0, context=0x7f9189ffe5c0, filename=<optimized
out>, lineno=0, size=0) at
./src/hotspot/share/utilities/vmError.cpp:1603
#4  0x00007f93c3c590cf in VMError::report_and_die(Thread*, unsigned
int, unsigned char*, void*, void*, char const*, ...)
    (thread=thread@entry=0x7f925c314000, sig=sig@entry=11,
pc=pc@entry=0x7f93c3348804
<AccessInternal::PostRuntimeDispatch<G1BarrierSet::AccessBarrier<109784
4ul, G1BarrierSet>, (AccessInternal::BarrierType)2,
1097844ul>::oop_access_barrier(void*)+4> "H\213\a\303\017\037\204",
siginfo=siginfo@entry=0x7f9189ffe6f0,
context=context@entry=0x7f9189ffe5c0,
detail_fmt=detail_fmt@entry=0x7f93c3d1348e "%s") at
./src/hotspot/share/utilities/vmError.cpp:1270
#5  0x00007f93c3c59102 in VMError::report_and_die(Thread*, unsigned
int, unsigned char*, void*, void*)
    (thread=thread@entry=0x7f925c314000, sig=sig@entry=11,
pc=pc@entry=0x7f93c3348804
<AccessInternal::PostRuntimeDispatch<G1BarrierSet::AccessBarrier<109784
4ul, G1BarrierSet>, (AccessInternal::BarrierType)2,
1097844ul>::oop_access_barrier(void*)+4> "H\213\a\303\017\037\204",
siginfo=siginfo@entry=0x7f9189ffe6f0,
context=context@entry=0x7f9189ffe5c0)
    at ./src/hotspot/share/utilities/vmError.cpp:1276
#6  0x00007f93c39b0d02 in JVM_handle_linux_signal(int, siginfo_t*,
void*, int)
    (sig=sig@entry=11, info=info@entry=0x7f9189ffe6f0,
ucVoid=ucVoid@entry=0x7f9189ffe5c0,
abort_if_unrecognized=abort_if_unrecognized@entry=1) at
./src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp:616
#7  0x00007f93c39a3fdc in signalHandler(int, siginfo_t*, void*)
(sig=11, info=0x7f9189ffe6f0, uc=0x7f9189ffe5c0) at
./src/hotspot/os/linux/os_linux.cpp:4693
#8  0x00007f93c4100950 in <signal handler called> () at /lib/x86_64-
linux-gnu/libc.so.6
#9 
AccessInternal::PostRuntimeDispatch<G1BarrierSet::AccessBarrier<1097844
ul, G1BarrierSet>, (AccessInternal::BarrierType)2,
1097844ul>::oop_access_barrier(void*) (addr=0x0)
    at ./src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp:66
#10 0x00007f93c36b0073 in AccessInternal::RuntimeDispatch<1097812ul,
oopDesc*, (AccessInternal::BarrierType)2>::load(void*)
(addr=0x7f91cd491060) at
./src/hotspot/share/oops/accessBackend.hpp:1325
#11 AccessInternal::PreRuntimeDispatch::load<1097812ul,
oopDesc*>(void*) (addr=0x7f91cd491060) at
./src/hotspot/share/oops/accessBackend.hpp:779
#12 AccessInternal::load_reduce_types<1097812ul, oopDesc*>(oopDesc**)
(addr=0x7f91cd491060) at
./src/hotspot/share/oops/accessBackend.hpp:1110
#13 AccessInternal::load<1048580ul, oopDesc*, oopDesc*>(oopDesc**)
(addr=0x7f91cd491060) at
./src/hotspot/share/oops/accessBackend.hpp:1211
#14 AccessInternal::OopLoadProxy<oopDesc*, 1048576ul>::operator
oopDesc*() (this=<optimized out>) at
./src/hotspot/share/oops/accessBackend.hpp:1326
#15 JNIHandles::resolve_impl<0ul, false>(_jobject*)
(handle=0x7f91cd491060) at
./src/hotspot/share/runtime/jniHandles.inline.hpp:60
#16 JNIHandles::resolve_non_null(_jobject*) (handle=0x7f91cd491060) at
./src/hotspot/share/runtime/jniHandles.inline.hpp:92
#17 get_method_id(jclass, char const*, char const*, bool, Thread*,
JNIEnv*)
    (clazz=clazz@entry=0x0, name_str=name_str@entry=0x7f915c3d3e8a
"fwkScheduleDispatchFunctions", sig=sig@entry=0x7f915c396304 "()V",
is_static=is_static@entry=true,
__the_thread__=__the_thread__@entry=0x7f925c314000, env=<optimized
out>) at ./src/hotspot/share/prims/jni.cpp:1336
#18 0x00007f93c36b040b in jni_GetStaticMethodID(JNIEnv*, jclass, char
const*, char const*)
    (env=<optimized out>, clazz=0x0, name=0x7f915c3d3e8a
"fwkScheduleDispatchFunctions", sig=0x7f915c396304 "()V") at
./src/hotspot/share/prims/jni.cpp:1382
#19 0x00007f915c0869e6 in WTF::scheduleDispatchFunctionsOnMainThread()
() at /home/matthias/.openjfx/cache/13/libjfxwebkit.so
#20 0x00007f915b2a745b in WTF::Function<void
()>::CallableWrapper<WebCore::DataURLDecoder::decode(WTF::URL const&,
WebCore::DataURLDecoder::ScheduleContext const&, WTF::Function<void
(WTF::Optional<WebCore::DataURLDecoder::Result>)>&&)::{lambda()#1}>::ca
ll() () at /home/matthias/.openjfx/cache/13/libjfxwebkit.so
#21 0x00007f915c089150 in WTF::Function<void
()>::CallableWrapper<WTF::WorkQueue::dispatch(WTF::Function<void
()>&&)::{lambda()#1}>::call() () at
/home/matthias/.openjfx/cache/13/libjfxwebkit.so
#22 0x00007f915c02215b in WTF::RunLoop::performWork() () at
/home/matthias/.openjfx/cache/13/libjfxwebkit.so
#23 0x00007f915c088190 in WTF::RunLoop::runImpl(WTF::RunLoop::RunMode)
() at /home/matthias/.openjfx/cache/13/libjfxwebkit.so
#24 0x00007f915c023867 in
WTF::Thread::entryPoint(WTF::Thread::NewThreadContext*) () at
/home/matthias/.openjfx/cache/13/libjfxwebkit.so
#25 0x00007f915c08a00d in WTF::wtfThreadEntryPoint(void*) () at
/home/matthias/.openjfx/cache/13/libjfxwebkit.so
#26 0x00007f93c4083590 in start_thread (arg=0x7f9189fff640) at
pthread_create.c:463
#27 0x00007f93c41d8223 in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:95

============================================================

What I also found is, that this is not a general problem of the WebView
on netbeans. I inserted seveal printf statements into the
MainThreadJava.cpp and JavaEnv.h files and found, that there are
several successful calls to isMainThread, but if fails for
scheduleDispatchFunctionsOnMainThread.

What I observe is, that the jclasses and jmethodID are resolved on each
invocation. The few times I work with JNI, the correspoding libraries
resolve the classids and methods at load time once and cache the
results for the lifetime of the library. Wouldn't this also be an
option for OpenJFX? From my observation, the jclasses can be found,
just not for the schedule.

Greetings

Matthias


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic