-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[GR-54648] JNIJavaCallTrampolineHolder.varargsJavaCallTrampoline
hides native crash
#9083
Comments
To reproduce the issue:
There is another target you can use which works, but doesn't use static JNI (instead it uses regular JNI with a regular shared library):
|
@sgammon , This is an interesting report. Thank you. |
JNIJavaCallTrampolineHolder.varargsJavaCallTrampoline
JNIJavaCallTrampolineHolder.varargsJavaCallTrampoline
Created internal ticket: GR-54648 |
Hey @fernando-valdez, We've tried on GVM latest release (Oracle GraalVM JDK 22). Here it is on Linux:
And on macOS:
FWIW, on other projects we build on GVM EE Dev, and I think I observed it there too (our latest release for that is |
JNIJavaCallTrampolineHolder.varargsJavaCallTrampoline
JNIJavaCallTrampolineHolder.varargsJavaCallTrampoline
hides native crash
@fernando-valdez I've determined that, actually, the underlying native libraries were failing to load -- this was true in both the case of SQLite and JNA. I've fixed static init in both libraries and GVM is processing them just fine. It seems to me, then, that this stacktrace shows the nearest call border with JNI, no matter where the crash actually occurred within native code. I updated the issue title to reflect this, and java-native-access/jna#1608 is unblocked. |
Thanks for the update |
What do you mean by were failing to load? |
I mean that the initialization steps in
This confused me too because it should be a call from Java → JNI. Unless this behavior could be triggered by init, where Netty is looking up classes, etc? But I don't suppose invocations of
Good point and thank you for the amazing crash reporter.
I think Netty was not handling JNI exceptions in this particular spot, and instead bailing early from init on errors from things like I have now learned a lot about JNI's internals and know that exception checking is necessary after crossing the VM border. Anyway, after fixing the |
Trampolines are also used for object allocations with constructor calls, besides "regular" method calls. Things like lookups don't use them.
Missing error handling in code using JNI is unfortunately extremely common and causes almost all such crashes which happen in different places and are hard to comprehend. |
Hello Native Image authors,
Summary
I am using a (admittedly undocumented) technique called Static JNI to load libraries inside a
native-image
binary. Namely, I'm working on enabling this for JNA.Static JNI is initialized for JNA's
libjnidispatch
here, like this:A static library,
libjnidispatch.a
, appears on-disk at build time, and is added to the build via the above logic.We can verify that the library links into the build; the linker command looks something like this:
The binary builds and even runs, but at the first callsite that uses static JNI, there is a crash:
Click to see full segfault
The crash happens on:
It always seems to happen at
com.oracle.svm.core.jni.JNIJavaCallTrampolineHolder.varargsJavaCallTrampoline(JNIJavaCallTrampolineHolder.java)
, regardless of which native (static JNI) call is hit. When we build the JNA sample (which is the reproducer attached), we get the same crash, but at JNA's first JNI callsite.Are we using Static JNI incorrectly? I understand that this technique is undocumented/unsupported, but we are happy to live with breakages until it becomes formal API. The benefits to our app of Static JNI could be significant, so we are willing to pursue this feature despite the brittleness it may imply. Thank you of course for any help you can offer.
The text was updated successfully, but these errors were encountered: