【发布时间】:2017-11-08 15:57:07
【问题描述】:
我正在使用 java + c++(使用 JNI),我必须加载自己的本机库,但在调用 throw 时应用程序因核心转储而失败,尽管代码被异常处理程序包围(参见下面的代码)。在 linux 64bit、sparc 64bit 和 i386 32bit 上运行相同的代码没有问题。
在英特尔 SunOs 上尝试在 java 8 下运行应用程序时出现问题。
标志 -m64 已添加到 Makefile,库已添加到 LD_PRELOAD_64 并且 LD_LIBRARY_PATH_64 已正确设置。
java 启动,成功加载库并运行原生代码(Java_com_jnetx_usw_chp_CHPMain_start)并在抛出时崩溃:
INF:17:59:33.20:CHP main(27): CHPMain.run: ok load chp library. Start it...
NOT:17:59:33.22:CHP main(27): CHPMain.run: -> chp.start
Wed Nov 8 17:59:34 CHP::startTest : cycle = 1
Wed Nov 8 17:59:35 CHP::startTest : cycle = 2
Wed Nov 8 17:59:35 Try cause Exception...
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x0000000000012ab5, pid=10081, tid=0x0000000000000026
#
# JRE version: Java(TM) SE Runtime Environment (8.0_121-b13) (build 1.8.0_121-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode solaris-amd64 compressed oops)
# Problematic frame:
# C 0x0000000000012ab5
#
# Core dump written. Default location: /home/kcc_64/x2001/bin/core or core.10081
#
# An error report file with more information is saved as:
# /home/kcc_64/x2001/bin/hs_err_pid10081.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#
本机代码
JNIEXPORT void JNICALL Java_com_jnetx_usw_chp_CHPMain_start
(JNIEnv *env, jobject jobj, jint trc_level,jobjectArray j_argv,jobject chp_main,jobject chp_smp)
{
chp = new CHP();
chp->startTest();
}
void CHP::startTest() {
int t = 1;
while (true) {
try {
poll(NULL, 0, 1000);
fprintf(stderr, "%s CHP::startTest : cycle = %d\n", getTime(), t++);
if ( 3 == t ) {
fprintf(stderr, "%s : Try generate Exception... \n", getTime());
throw 20;
}
}
catch (const int & e) {
fprintf(stderr, "%s : Catch, e = %d\n", getTime(), e);
break;
}
catch (...) {
fprintf(stderr, "%s : Catch unknown exception...\n", getTime());
break;
}
}
fprintf(stderr, "%s : CHP::startTest : End thread, exit\n", getTime());
}
为什么 catch 块被忽略,我们立即转到以核心转储结束的系统信号处理程序(参见下面的 pstack)?
-bash-3.00$ unname -a SunOS x2001 5.10 Generic_142910-17 i86pc i386 i86pc -bash-3.00$ pstack 核心
-bash-3.00$ gcc --version 海合会 (GCC) 4.4.2 版权所有 (C) 2009 Free Software Foundation, Inc. 这是免费软件;查看复制条件的来源。没有 保修单;甚至不考虑适销性或特定用途的适用性。
pflags core
/38: flags = DETACH
sigmask = 0xfffffeff,0x0000ffff cursig = SIGABRT
pstack core
fffffd7fff291aea _lwp_kill () + a
fffffd7fff236c39 raise () + 19
fffffd7fff215bb0 abort () + 90
...
fffffd7ffe9d0343 JVM_handle_solaris_signal () + 8d7
fffffd7ffe9c8617 signalHandler () + 2f
fffffd7fff28c2e6 __sighndlr () + 6
fffffd7fff280bc2 call_user_handler () + 252
fffffd7fff280dee sigacthandler (b, fffffd7f7e2f5208, fffffd7f7e2f4ea0) + ee
--- called from signal handler with signal 11 (SIGSEGV) ---
0000000000013dd5 ???????? () + 28000d930d5
fffffd7fff2904d9 _SUNW_Unwind_RaiseException () + 46
fffffd7f7dea2c53 __cxa_throw () + 9b !!!!!!!!!
fffffd7f7f213310 _ZN3CHP9startTestEv () + 190
fffffd7fee215a14 * com/jnetx/usw/chp/CHPMain.start(I[Ljava/lang/String;Lcom/jnetx/usw/chp/CHPMain;Lcom/jnetx/usw/chp/CHPSmp;)V+0
fffffd7fee2083b6 * com/jnetx/usw/chp/CHPMain.run([Ljava/lang/String;Lcom/jnetx/usw/chp/CHPUpdateListener;)V+563 (line 377)
fffffd7fee2083b6 * com/jnetx/usw/chp/CHPProvider$1.run()V+20 (line 374)
fffffd7fee2007a7 * com/jnetx/usw/chp/CHPProvider$1.run()V+17760
fffffd7ffe4c10ff __1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_ () + 8d7
fffffd7ffe4bcd3c __1cJJavaCallsMcall_virtual6FpnJJavaValue_nLKlassHandle_pnGSymbol_5pnRJavaCallArguments_pnGThread__v_ () + 424
fffffd7ffe4bd124 __1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_pnGSymbol_6pnGThread__v_ () + 60
fffffd7ffe64030c __1cMthread_entry6FpnKJavaThread_pnGThread__v_ () + b8
fffffd7ffebd9679 __1cKJavaThreadDrun6M_v_ () + 5e1
fffffd7ffe9bdc85 java_start () + 175
fffffd7fff28bfbb _thr_setup () + 5b
fffffd7fff28c1e0 _lwp_start ()
【问题讨论】:
-
JVM 是否已经使用 C++ 运行时库?如果有,是什么版本?
-
我在哪里以及如何收到这些信息?
-
我自己的库已经被 gcc 4.4 版本编译和链接到它的个人库:
-
g++ -g -O2 -m64 -DSOLARIS -DSUNI386 -m64 -D_REENTRANT -fPIC -DTSD -Wall -Wextra -std=c++0x -shared -o libchp.so ../tmp/ memtest.o -L../tmp -lpthread -lrt -lsocket -lposix4 -lumem -ldemangle -lrt -bash-3.00$ ldd libchp.so libstdc++.so.6 => /usr/local/gcc4/lib/amd64/ libstdc++.so.6 libgcc_s.so.1 => /usr/local/gcc4/lib/amd64/libgcc_s.so.1
-
从 java 加载的库(获取 frpom /proc/$PID_JAVA/path):lrwxrwxrwx 1 vb rnd1 0 Nov 9 12:56 nfs.311.1559.269661 -> /home/x2001/lib/native/ sunos/i386/libchp.so lrwxrwxrwx 1 vb rnd1 0 Nov 9 12:56 ufs.30.0.251041 -> /usr/local/gcc4/lib/amd64/libgcc_s.so.1 lrwxrwxrwx 1 vb rnd1 0 Nov 9 12:56 ufs.30.0.251065 -> /usr/local/gcc4/lib/amd64/libstdc++.so.6.0.13
标签: java c++ java-native-interface 64-bit solaris