Как отлаживать 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 T debug .так файлы?

3 ответов


  1. запустите приложение java
  2. найдите pid, используя top, ps,...
  3. запустите gdb с этим pid
  4. прикрепите код программы
  5. отладка как обычно с помощью gdb

этот блог в должности объясняет все дело.


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

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

Я просто адаптировал концепцию из статьи здесь : 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/C++ и отладчиком Java. Вы просто нужно запустить оба сеанса отладки: java и удаленный C / C++ , который работает на 127.0.0.1: 11337.


ссылке ТМ.Саурон прав, но было бы менее удобно, когда у нас есть много параметров для передачи команде java, как мой проект имеет около нескольких строк param для передачи. Поэтому в этом случае мы можем использовать IDE для запуска приложения и его разрыва, чтобы указать, когда мы хотим отлаживать в родной библиотеке. Конечно, собственная библиотека должна быть создана в режиме отладки.