JRE fatal error SIGSEGV only occurs when executing native code through JNI

1,174 views
Skip to first unread message

Josh Broadway

unread,
Sep 4, 2013, 12:05:57 AM9/4/13
to jna-...@googlegroups.com
Hi,

We have a Java EE application running in JBoss that uses JNA (3.5.1) to make a call to a Native C++ library on RedHat 6.3. 

The C++ library we were using used to be 32-bit but has recently been ported to 64-bit. We are now in the process of updating JBoss application to run using the 64-bit JVM (RHEL JRE 1.6_43.1).

When we ported the Native library to 64-bit we used a C++ test stub to test all of the public interfaces that are used by JNA - all of these tests pass without any problems.

Now, when I try to access the 64-bit Native library using JNA I get the following error:

#
# A fatal error has been detected by the Java Runtime Environment

#  SIGSEGV (0xb) at pc=0x0000003718b32fbc, pid=4489, tid=140200254654208
#
# JRE version: 6.0_22-b22
# Java VM: OpenJDK 64-Bit Server VM (20.0-b11 mixed mode linux-amd64 compresssed oops)
# Derivative: IcedTea6 1.10.6
# Distribution: Red Hat Enterprise Linux Server release 6.2 (Santiago), package rhel-1.43.1.10.6.el6_2-x86_64
# Problematic frame:
# C  [libc.so.6+0x132fbc]  __tls_get_addr@@GLIBC_2.3+0x132fbc
#
# ...

I have traced the source of the error down to a call that is being made to a third party library that is called from within our recently ported Native library. The call to the third party library is being made with a set of values that originate from within the Native library, not values that get passed into the library.

So for SOME REASON we get the following behaviour: 

- Call Native library from C++ test stub: Success 

- Call Native library from Java via JNA: Failure (segfault)


The native interface being used is:
 extern "C"
{
    const char* getId(const char* interface);
    int isValidFeature(const char* feature, const char* interface);
}

And the JNA mapping is:
public interface NativeInterface extends Library
{
    boolean isValidFeature (String feature, String interface);
    String getHostId(String interface); 
}

I'm running out of ideas about what the problem could be and my lack of knowledge of both JNA and C++ is seriously holding me back (I come from a largely Java team and drew the short straw in getting this task). If anyone has any information, pointers, advice, etc. it would be greatly appreciated. 

Thanks,
Josh.

Timothy Wall

unread,
Sep 4, 2013, 1:17:47 AM9/4/13
to jna-...@googlegroups.com
It'd certainly help to be able to attach a debugger, and run with debug versions of the libraries in question.

It might be an issue with simultaneous linkage of different versions of glibc; can you rebuild JNA (w/native bits) on your target system, or the same system on which the native C++ library was built?
> --
> You received this message because you are subscribed to the Google Groups "Java Native Access" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Josh Broadway

unread,
Sep 9, 2013, 4:03:59 AM9/9/13
to jna-...@googlegroups.com
Hi Tim,

Thanks for the response. Unfortunately the library that's causing the SIGSEGV error is a 3rd party library that we can't look into or turn debugging on for. So there's not much that can be done in that area.

I guess the thing that most interests me with this problem is that the code runs fine when invoked from a C++ app but not when invoked through JNA. What is the difference between JNA and using a native library? Different libc versions? Different memory addressing? I'm clutching at straws.

One other idea that I'm trying to follow up is whether JNA/JNI is less 'robust' than using a C++ app. Is it possible the error is occurring when I invoke the library through the C++ app the same memory error occurs but it doesn't escalate up to cause the whole program to crash? I don't know... this certainly isn't my area of expertise.

I guess the only other development of note since I originally posted the problem is that I have written a JNI interface to try to see if the problem was something specific to JNA and I get the same problem when invoking the library through JNI. So this isn't a JNA-specific problem.

Cheers,
Josh.

Timothy Wall

unread,
Sep 9, 2013, 7:48:11 AM9/9/13
to jna-...@googlegroups.com

On Sep 9, 2013, at 4:03 AM, Josh Broadway wrote:

> Hi Tim,
>
> Thanks for the response. Unfortunately the library that's causing the SIGSEGV error is a 3rd party library that we can't look into or turn debugging on for. So there's not much that can be done in that area.
>
> I guess the thing that most interests me with this problem is that the code runs fine when invoked from a C++ app but not when invoked through JNA. What is the difference between JNA and using a native library? Different libc versions? Different memory addressing? I'm clutching at straws.

The most likely thing is improper type mapping at the API. You might try running JNAerator on the headers to see if there are any obvious discrepancies. Fundamentally the linking is the same: dlopen, dlsym, etc.

Different libc versions *might* be an issue, but I've not seen any actual issues with that other than having a libc version that was too new, such that the library, when loaded, was missing libc symbols.

>
> One other idea that I'm trying to follow up is whether JNA/JNI is less 'robust' than using a C++ app. Is it possible the error is occurring when I invoke the library through the C++ app the same memory error occurs but it doesn't escalate up to cause the whole program to crash? I don't know... this certainly isn't my area of expertise.
>
> I guess the only other development of note since I originally posted the problem is that I have written a JNI interface to try to see if the problem was something specific to JNA and I get the same problem when invoking the library through JNI. So this isn't a JNA-specific problem.

If you think it might be an errant C++ exception, put try/catch blocks in your failing JNI calls. JNA has a protected mode (suitable only for debugging on non-windows systems) that can catch segfaults (Native.setProtected(true)) when properly configured (you also need to set LD_PRELOAD to point to libjsig.so -- see docs).

The fact that JNI code is failing as well would tend to point away from libc linkage issues.

Given that this is a 64- vs 32-bit port, I'd especially focus on any native long parameters/fields/values (4 bytes on 32-bit, 8 bytes on 64-bit).
Reply all
Reply to author
Forward
0 new messages