Java JNI Launcher в C ++: работает без JavaFX, Core Dump с JavaFX - PullRequest
0 голосов
/ 30 ноября 2018

Я написал C ++ JNI Java Launcher.Это работает, если я запускаю Java-программу, которая не использует JavaFX, но создает дамп ядра, если я пытаюсь запустить программу JavaFX вместе с ней.Вот код:

Без JavaFX - launch.cpp

С JavaFX - launch.ccp

Только дамп ядрапроисходит, если я использую свой родной лаунчер.Если я запускаю программу JavaFX с теми же аргументами, используя java в командной строке, проблем не возникает.Это работает, как ожидалось.

Вот содержимое файла hs_err в виде вставки.

Вместо того, чтобы вставлять код из нескольких файлов, я создал хранилище с двумя ветвями с полнымуправляемые примеры.

Полный пример - без JavaFX

Полный пример - с JavaFX

Вы можете запустить примеры, отредактировав build.shи run-native.sh и изменение строки jdk="/usr/lib/jvm/java-11-oracle", чтобы быть точным для вашей системы.Затем:

./build.sh          #compiles the java program and cpp program
./run-native.sh     #Sets LD_LIBRARY_PATH and runs the compiled cpp program
   or
./run-with-java.sh  #only on "withjfx" branch, runs via java at cli. 

Как вы должны видеть, версия No JavaFX работает нормально, но версия JavaFX запускается только через вызов исполняемого файла java, она выгружается из ядра, если выполняется через мою собственную программу запуска.

Наконец, вот дамп, который я получаю, когда пытаюсь запустить версию JavaFX с помощью собственного средства запуска:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f77513575d8, pid=15281, tid=15301
#
# JRE version: Java(TM) SE Runtime Environment (11.0.1+13) (build 11.0.1+13-LTS)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.0.1+13-LTS, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# j  java.util.Arrays$ArrayList.<init>([Ljava/lang/Object;)V+6 java.base@11.0.1
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P" (or dumping to /home/joshua/work/javalaunch/core.15281)
#
# An error report file with more information is saved as:
# /home/joshua/work/javalaunch/hs_err_pid15281.log
Compiled method (c2)     326  208       4       java.util.Objects::requireNonNull (14 bytes)
 total in heap  [0x00007f7758e10d90,0x00007f7758e10fc8] = 568
 relocation     [0x00007f7758e10f08,0x00007f7758e10f18] = 16
 main code      [0x00007f7758e10f20,0x00007f7758e10f60] = 64
 stub code      [0x00007f7758e10f60,0x00007f7758e10f78] = 24
 metadata       [0x00007f7758e10f78,0x00007f7758e10f80] = 8
 scopes data    [0x00007f7758e10f80,0x00007f7758e10f90] = 16
 scopes pcs     [0x00007f7758e10f90,0x00007f7758e10fc0] = 48
 dependencies   [0x00007f7758e10fc0,0x00007f7758e10fc8] = 8
Could not load hsdis-amd64.so; library not loadable; PrintAssembly is disabled
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
./run-native.sh: line 6: 15281 Aborted                 (core dumped) ./bin/launch

По рекомендации пользователя, основанной на предыдущем сбое, яустановил hsdis-amd64.so на мою систему и указал LD_LIBRARY_PATH на нее.Я по-прежнему получаю дамп ядра, похоже, все, что он делал, это позволяло дампу ядра загружать дизассемблер:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f9e6e2015d8, pid=17530, tid=17550
#
# JRE version: Java(TM) SE Runtime Environment (11.0.1+13) (build 11.0.1+13-LTS)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.0.1+13-LTS, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# j  java.util.Arrays$ArrayList.<init>([Ljava/lang/Object;)V+6 java.base@11.0.1
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P" (or dumping to /home/joshua/work/so-question/core.17530)
#
# An error report file with more information is saved as:
# /home/joshua/work/so-question/hs_err_pid17530.log
Compiled method (c2)     372  187       4       java.util.Objects::requireNonNull (14 bytes)
 total in heap  [0x00007f9e75cbb890,0x00007f9e75cbbac8] = 568
 relocation     [0x00007f9e75cbba08,0x00007f9e75cbba18] = 16
 main code      [0x00007f9e75cbba20,0x00007f9e75cbba60] = 64
 stub code      [0x00007f9e75cbba60,0x00007f9e75cbba78] = 24
 metadata       [0x00007f9e75cbba78,0x00007f9e75cbba80] = 8
 scopes data    [0x00007f9e75cbba80,0x00007f9e75cbba90] = 16
 scopes pcs     [0x00007f9e75cbba90,0x00007f9e75cbbac0] = 48
 dependencies   [0x00007f9e75cbbac0,0x00007f9e75cbbac8] = 8
Loaded disassembler from hsdis-amd64.so
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
./run-native.sh: line 6: 17530 Aborted                 (core dumped) ./bin/launch

Обновление: я продублировал эту проблему на Ubuntu 18.04 и Windows 7.

1 Ответ

0 голосов
/ 01 декабря 2018

Я понял это.Проблема в строке 35 с аргументами, которые передаются основным методом JVM:

env->CallStaticVoidMethod( cls, main, " ");

Мы передаем c-строку в Java, где java ожидает java.lang.String [].Как только кто-то пытается прочитать этот аргумент, JVM падает.JavaFX должен прочитать аргументы в некоторый момент между main и start (), и в результате произойдет сбой.

Правильная строка - либо

env->CallStaticVoidMethod( cls, main, "(I)V"); (я не проверял этот, но это общая строка из примера кода, предоставленного java людьми)

или:

jclass classString = env->FindClass("java/lang/String");
jobjectArray argsToJava = env->NewObjectArray(0, classString, NULL);
env->CallStaticVoidMethod( cls, main, argsToJava );
...