我正在使用JNA
从Java / Scala接收本机Fortran库(物理),使用Apache Spark分布式计算框架调用。
使用我的库/opt/MYORG/hdd/usr/local/lib/mylib.so
编译ifort
和调试编译器选项
-shared -fPIC -save -g -check all -fpe0 -traceback -static -static-intel -Bstatic
我的执行程序不时崩溃,因为SIGSEGV
,由JVM错误指示 - 报告:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fea0f490700, pid=33080, tid=140647778658048
#
# JRE version: Java(TM) SE Runtime Environment (8.0_60-b27) (build 1.8.0_60-b27)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.60-b23 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C 0x00007fea0f490700
我设法创建了一个用
分析的核心转储gdb /usr/java/jdk1.8.0_60/bin/java core.33080
(gdb) bt
#0 0x00007fed0a04f1d7 in raise () from /usr/lib64/libc.so.6
#1 0x00007fed0a0508c8 in abort () from /usr/lib64/libc.so.6
#2 0x00007fed0995b6b5 in os::abort(bool) () from /usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so
#3 0x00007fed09af9bf3 in VMError::report_and_die() () from /usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so
#4 0x00007fed09960edf in JVM_handle_linux_signal () from /usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so
#5 0x00007fed09957673 in signalHandler(int, siginfo*, void*) () from /usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so
#6 <signal handler called>
#7 0x00007fea0f490700 in ?? ()
#8 0x00007fed0a7fcbc2 in __nptl_deallocate_tsd () from /usr/lib64/libpthread.so.0
#9 0x00007fed0a7fcdd3 in start_thread () from /usr/lib64/libpthread.so.0
#10 0x00007fed0a11173d in clone () from /usr/lib64/libc.so.6
我用
进一步分析了核心thread apply all bt full
但是我没有看到任何线程当前在我自己的(可能有问题的)库mylib.so
中,所有线程似乎都在等待。到目前为止,没有任何内容指向mylib.so
导致SIGSEGV
的事实,但如果我在代码中用模拟替换mylib.so
的调用(即没有实际的本机调用),则不SIGSEGV
出现,因此我得出结论,问题必须在JNA调用我的本机库中。
到目前为止,我尝试了以下提示:https://software.intel.com/en-us/articles/determining-root-cause-of-sigsegv-or-sigbus-errors但没有成功
有人可以帮助我查找上述SIGSEGV
的原因吗?
答案 0 :(得分:0)
这种错误是非常讨厌的。您可以尝试应用以下模式:
http://jnicookbook.owsiak.org/recipe-No-015/
在这种方法中,您可以在代码中“捕获”SIGSEGV。然后,您可以尝试使用backtrace函数获取回溯:
void *array[100];
size_t size;
size = backtrace (array, 100);
backtrace_symbols_fd (array, size, STDOUT_FILENO);
请注意,你不应该在信号处理程序内部做太多。
然后,如果运气好的话,你就能发现问题的原因。
另一种方法是使用gdb实际调试JVM,看看那里会发生什么。
您可以在此处找到JNI调试示例:
或在这里:
http://jnicookbook.owsiak.org/recipe-No-D002/
或在这里:
正如已经建议的那样,尝试在Fortran代码中启用边界检查。有时它会有所帮助。
我希望它会有所帮助。
与JNI / JNA玩得很开心。