web-dev-qa-db-ja.com

LinuxでGDBを使用してJava -JNIをデバッグする方法は?

誰かがGDBデバッガーを使用してLinuxでJNIコードをデバッグする方法についてガイドできますか(可能であれば他のオプションを提案してください)。

    -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をインストールしましたが、それを使用してプロジェクトをデバッグする方法がわかりません。また、-gオプションを使用して.cppファイルをコンパイルする必要がありますか?.soファイルをデバッグしますか?

17
Twaha Mehmood
  1. Javaアプリケーションを起動します
  2. Top、ps、..を使用してpidを検索します。
  3. このpidでgdbを起動します
  4. プログラムコードを添付してください
  5. Gdbを使用して通常どおりデバッグする

このブログ 投稿 すべてを説明しています。

15
jackrabbit

次の方法は本当に面白いと思いました。以下のファイルをデバッグするjniライブラリにリンクすることにより、ライブラリがダイナミックリンカによってロードされると、gccコンストラクタ属性のおかげで現在のjvmのgdbserverが自動的に起動します。

コマンドラインまたはEclipseからリモートgdbを使用するだけで、デバッグが簡単になります。デバッグモードでビルドする場合、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がインストールされ、開発用PCにgdb-multiarchがインストールされている組み込みデバイスでのデバッグも可能です。

Eclipse内からデバッグしている間、C/C++デバッガーとJavaデバッガーの間で自動的にジャンプします。両方のデバッグセッションを開始する必要があります:Java 1つと127.0.0.1:11337で実行されるリモートC/C++。

2
daminetreg

Link by tm.sauronは正しいですが、Javaコマンドに渡すパラメーターがたくさんある場合は、プロジェクトに渡すパラメーターが数行あるように、あまり便利ではありません。したがって、その場合は、IDEを使用してアプリケーションを起動し、ネイティブライブラリでデバッグするときにポイントに分割できます。もちろん、ネイティブライブラリはデバッグモードで作成する必要があります。

0
twid