Как отладить Java -JNI с помощью GDB на Linux?

Может ли кто-нибудь объяснить, как отлаживать код JNI в Linux с помощью отладчика GDB (если возможно, предложите другие варианты).

    -My JNI project when running on Linux is leading to a JVM crash.
    -The CPP code has been compiled into .so files.
    -I run the project like  this : *java xyz.jar -commandline_args_to_project*.

У меня установлен Gdb, но я не понимаю, как мы можем отлаживать проект, используя его. Также мне обязательно нужно скомпилировать файлы .cpp с параметрами -g для отладки .so файлов?

Ответ 1

  • Запустите приложение Java.
  • Посмотрите pid, используя top, ps,...
  • Запустите gdb с помощью этого pid
  • Прикрепите свой программный код
  • Отладка, как обычно, с помощью gdb

Этот блог post объясняет все это.

Ответ 2

Я нашел следующий способ действительно интересным. Связывая файл ниже с библиотекой jni, которую вы хотите отлаживать, когда библиотека загружается динамическим компоновщиком, она автоматически запускает gdbserver для текущего jvm, благодаря атрибуту конструктора gcc.

Просто используя удаленный gdb из командной строки или из eclipse, вы легко отлаживаете его. Я только устанавливаю, что, если я создам в режиме отладки, я пока не реализовал, чтобы определить, запущен ли jvm в отладке, разрешить это только в этот момент, но может быть легко.

Я просто адаптировал концепцию из статьи здесь: http://www.codeproject.com/Articles/33249/Debugging-C-Code-from-Java-Application

#ifndef NDEBUG // If we are debugging

#include <stdlib.h>
#include <iostream>
#include <sstream>

namespace debugger {
    static int gdb_process_pid = 0;

    /**
     * \brief We create a gdb server on library load by dynamic linker, to be able to debug the library when java begins accessing it.
     * Breakpoint have naturally to be set.
     */
    __attribute__((constructor))
    static void exec_gdb() {
        // Create child process for running GDB debugger
        int pid = fork();

        if (pid < 0) {
            abort();

        } else if (pid) {
            // Application process

            gdb_process_pid = pid; // save debugger pid
            sleep(10); /* Give GDB time to attach */

            // Continue the application execution controlled by GDB
        } else /* child */ {
            // GDBServer Process

            // Pass parent process id to the debugger
            std::stringstream pidStr;
            pidStr << getppid();

            // Invoke GDB debugger
            execl("/usr/bin/gdbserver", "gdbserver", "127.0.0.1:11337", "--attach", pidStr.str().c_str(), (char *) 0);

            // Get here only in case of GDB invocation failure
            std::cerr << "\nFailed to exec GDB\n" << std::endl;
        }
    }
}
#endif

Кроме того, он также позволяет отлаживать встроенные устройства с установленным gdbserver и gdb-multiarch на вашем компьютере разработки.

Во время отладки из eclipse он автоматически переходит между отладчиком C/С++ и отладчиком Java. Вам просто нужно запустить оба сеанса отладки: java-один и удаленный C/С++, который работает на 127.0.0.1:11337.

Ответ 3

Ссылка от tm.sauron верна. Но было бы менее удобно, когда у нас было много параметров для перехода к java-команде, так как мой проект имеет около нескольких строка парама. Таким образом, в этом случае мы можем использовать IDE для запуска приложения и разбиения его на точку, когда мы хотим отлаживать исходную библиотеку. В режиме отладки необходимо создать собственную библиотеку.