Зависает вызов Java System.LoadLibrary в Linux

#java #linux #shared-libraries

#java #linux #разделяемые библиотеки

Вопрос:

У меня очень маленький .файл so (доступен здесь: https://docs.google.com/leaf?id=0B4MxFm-ACB3INjhkMjhlNzktYzkxYy00Zjk5LTk0Y2MtZDE2MWQ2MzY1OWUyamp;hl=en_USamp;authkey=CMrJguwN )

Я пытаюсь загрузить это в Java на RHEL, и Java main просто зависает (без ошибок или исключений). У меня есть каталог с файлом .so в LD_LIBRARY_PATH, поэтому я знаю, что он на самом деле пытается его загрузить.

Есть какие-нибудь идеи, как я могу устранить это?

 public class SmallTester {


    public static void main(String[] args){

        for(String s: System.getenv("LD_LIBRARY_PATH").split(":")){
            System.out.println(s);
        }

        System.loadLibrary("TestAda");

        System.out.println("Here");
    }
}
  

Редактировать:

Основываясь на приведенном ниже сообщении, я сделал strace.. Похоже, что он повторяет этот вызов снова и снова (хотя я не уверен, что это значит?):

 [pid 31464] clock_gettime(CLOCK_MONOTONIC, {3605675, 624255544}) = 0
[pid 31464] gettimeofday({1306417113, 168967}, NULL) = 0
[pid 31464] clock_gettime(CLOCK_MONOTONIC, {3605675, 624435576}) = 0
[pid 31464] clock_gettime(CLOCK_MONOTONIC, {3605675, 624518205}) = 0
[pid 31464] gettimeofday({1306417113, 169216}, NULL) = 0
[pid 31464] clock_gettime(CLOCK_REALTIME, {1306417113, 169306590}) = 0
[pid 31464] futex(0x88b3f04, FUTEX_WAIT_PRIVATE, 1, {0, 49909410}) = -1 ETIMEDOUT (Connection timed out)
  

Вот полная версия журнала: https://docs.google.com/leaf?id=0B4MxFm-ACB3IYzdhZWIwNWEtYjUzMS00NGM5LWEzZjQtYzMzOWE3MWNhYWQ0amp;hl=en_USamp;authkey=CJ-Lv_wG

ПРАВКА2: Я также пытался загрузить библиотеку с помощью JNA:

 public class SmallTesterJNA {

    public interface CLibrary extends Library {

      CLibrary INSTANCE1 = (CLibrary)
      Native.loadLibrary("TestAda", //  <<< our library goes here
                         CLibrary.class);

    }

    public static void main(String[] args){

        for(String s: System.getenv("LD_LIBRARY_PATH").split(":")){
            System.out.println(s);
        }

        System.loadLibrary(CLibrary.INSTANCE1.toString());

        System.out.println("Here");
    }
}
  

Вот результат.. Это выглядит очень похоже: https://docs.google.com/leaf?id=0B4MxFm-ACB3IYzdhZWIwNWEtYjUzMS00NGM5LWEzZjQtYzMzOWE3MWNhYWQ0amp;hl=en_USamp;authkey=CJ-Lv_wG

Правка2:

Вот мой вывод gcore, прикрепленный к процессу.. не уверен, о чем это мне говорит:

 (no debugging symbols found)
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[New Thread 0xb7fb26c0 (LWP 8326)]
[New Thread 0x7fa8eb90 (LWP 8340)]
[New Thread 0x7fe2db90 (LWP 8339)]
[New Thread 0x7fe7eb90 (LWP 8338)]
[New Thread 0x7feffb90 (LWP 8337)]
[New Thread 0x800afb90 (LWP 8336)]
[New Thread 0x80100b90 (LWP 8335)]
[New Thread 0x80351b90 (LWP 8334)]
[New Thread 0x803a2b90 (LWP 8333)]
[New Thread 0x80423b90 (LWP 8332)]
[New Thread 0x8066db90 (LWP 8331)]
[New Thread 0x806eeb90 (LWP 8330)]
[New Thread 0x8076fb90 (LWP 8329)]
[New Thread 0x807f0b90 (LWP 8328)]
[New Thread 0xb7474b90 (LWP 8327)]
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
0xb7fcd402 in __kernel_vsyscall ()
Saved corefile core.8326
  

Ответ №1:

Если бы мне пришлось гадать, я бы сказал, что вероятным виновником является код инициализации общего объекта.

Возьмите дамп ядра вашего процесса JVM (с помощью gcore ) или прикрепите gdb , чтобы получить трассировку стека, где именно он зависает.

Ответ №2:

Обычно я пробую strace перед gdb (отслеживание всех системных вызовов). Выполнить:

 strace -f java SmallTester > logfile 2>amp;1
  

Вы получите много информации в файле журнала, последняя часть самая интересная. Вы обнаружите, что процесс jvm ищет ваш TestAda.so файл и посмотрите, успешно ли он загрузил файл .so. Если это не сработает, вернитесь к gdb.

Комментарии:

1. Можете ли вы просмотреть файл журнала выше? Есть идеи, что происходит?

2. Я не думаю, что проблема в [pid 31464], это просто поток Java, ожидающий чего-то. Насколько я вижу, jvm нашла вашу библиотеку в /adapts/ad/irad-c2/builds/mark/workspace/ASOC_M/mukul-branch/Omnyx/Projects/Test/buildLinux-i686/lib/libTestAda. итак, это вызвало загрузку libgnarl-6.2.so , libgnat-6.2.so и libgcc_s.so.1. После некоторой инициализации поток / процесс остановился (например, системные вызовы не выполнялись), поэтому либо он бесконечно вращается в коде инициализации (CPU на 100%?), либо он блокируется при некоторой блокировке.

Ответ №3:

Взгляните на свою JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) функцию в вашем коде на C . Это может иметь бесконечный цикл 🙂 Также попробуйте определить это, если оно еще не определено.

Смотрите здесь для получения подробной информации о JNI_OnLoad .

Комментарии:

1. На самом деле это библиотека Ada.. Все еще пытаюсь переварить этот пост с точки зрения того, что я делаю

2. Если вы используете JNI, вы не можете просто загрузить библиотеку Ada и ожидать, что будете использовать ее сразу. Вам нужно связать его с JNI, что означает создание функций, которые действуют как мост между Java и C . Похоже, что он запутывается, возможно, выполняя код инициализации DLL, который вызывает эти проблемы (возможно, в этом коде есть цикл вращения).

3. Если вы хотите сделать такую вещь, вам нужно вместо этого использовать JNA. Но имейте в виду, что код инициализации все еще может вас запутать.

4. Странно то, что этот точно такой же вызов работает в Solaris.. (Без JNI). Я просто пытаюсь перенести этот вызов в Linux и сталкиваюсь с этой проблемой.

5. Похоже, это связано с вашей проблемой: lists.globus.org/pipermail/gt-user/2010-February/008779.html