LINUX.ORG.RU

JNI код падает в core dump когда в коде вызывается throw на 64 bit SunOs

 , , , ,


1

3
-bash-3.00$ uname -a SunOS x2001 5.10 Generic_142910-17 i86pc i386 i86pc
-bash-3.00$ gcc --version gcc (GCC) 4.4.2 Copyright (C) 2009 Free Software Foundation, Inc. This is free software; see the source for copying conditions.

Написан код на java и c++ ( using JNI ) Но когда вызывается исключение, обработка не попадает в свой catch обработчик, а вызывается сразу системный и приложение падает в корку Тот же самый код прекрасно работает на linux 64bit, sparc 64bit and i386 32bit.

Проблема возникает при попытке запуска под 8 java ( по дефолту только 64 бита поддерживается) на intel SunOs.

Флаг -m64 был добавлен в Makefile и библиотека была добавлена в LD_PRELOAD_64 и в LD_LIBRARY_PATH_64 (и также без в LD_PRELOAD+LD_LIBRARY_PATH).

java успешно запускается и вызывает нативную функцию (Java_com_jnetx_usw_chp_CHPMain_start) но падает при вызове throw ( см. код, лог и трэйс ниже):

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 блок а попадает сразу в __cxa_throw?

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 ()

линковка тестового приложения

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

lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 nfs.311.1559.269661 -> /home/kcc_64/x2001/lib/native/sunos/i386/libchp.so
...
lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 ufs.30.0.233011 -> /opt/omni/library/libgcc_s.so.1
lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 ufs.30.0.233028 -> /opt/omni/library/libstdc++.so.6
lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 ufs.30.0.262550 -> /usr/jdk1.8.0_121/jre/lib/amd64/server/libjvm.so
lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 ufs.30.0.3355 -> /usr/lib/amd64/libCrun.so.1
...
lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 ufs.30.0.9059 -> /lib/amd64/libmd.so.1
lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 ufs.30.0.9061 -> /lib/amd64/libmp.so.2
lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 ufs.30.0.9062 -> /lib/amd64/libnsl.so.1


Последнее исправление: sccp (всего исправлений: 1)

Ты не там ловишь эксепшен. У тебя в твоем странном имени функции есть JNIEnv *env, у которого есть метод ThrowNew, через него и кидай эксепшен в Java.

xpahos ★★★★★
()
Последнее исправление: xpahos (всего исправлений: 1)
Ответ на: комментарий от xpahos

насколько я понял у TC в cpp коде cpp exceptionы не ловятся.

lberserq
()
-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

lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 ufs.30.0.233011 -> /opt/omni/library/libgcc_s.so.1
lrwxrwxrwx   1 vb rnd1  0 Nov  9 11:03 ufs.30.0.233028 -> /opt/omni/library/libstdc++.so.6

Такой фигни быть не должно. Ты компилируешь библиотеку с одним рантаймом, а используешь с другим. Либо линкуй в неё рантайм статически, либо компилируй тем же компилятором, что и JVM (и с теми же библиотеками).

asaw ★★★★★
()
Последнее исправление: asaw (всего исправлений: 2)

как вариант ставить бряку на throw и смотреть что в таблице обработчиков. либо смотреть на asm того что сгенерилось, смахивает на баг в gcc/некорректную установку его

lberserq
()

Почему обработка не попадает в catch блок а попадает сразу в __cxa_throw?

__cxa_throw — это еще не обработка, а выброс исключения (такая имплементация).

KennyMinigun ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.