[ACCEPTED]-How to Debug Java -JNI using GDB on linux ?-shared-libraries

Accepted answer
Score: 19
  1. Start your java application
  2. Look up the pid using top, ps, ...
  3. Start gdb with this pid
  4. Attach your program code
  5. Debug as usual using gdb

This blog post explains the whole thing.

0

Score: 2

I found the following way really interesting. By 20 linking the file below to the jni library 19 you want to debug, when the library get 18 loaded by the dynamic linker it automatically 17 starts a gdbserver for the current jvm, thanks 16 to the gcc constructor attribute.

Simply 15 using remote gdb from command line or from 14 eclipse make it easy to debug then. I only 13 setup that if I build in debug mode, I haven't 12 implemented for the moment to detect if 11 jvm was started in debug, to only allow 10 this at this moment, but could be easy.

I 9 simply adapted the concept from the article 8 here : 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

Additionally it also allows debugging 7 on embedded devices with gdbserver installed 6 and gdb-multiarch on your development pc.

While 5 debugging from within eclipse it jump automatically 4 between the C/C++ debugger and the Java 3 debugger. You just have to start both debugging 2 session : the java one and the remote C/C++ one 1 which runs on 127.0.0.1:11337.

Score: 0

Link by tm.sauron is right But would be less 7 convenient when we have many parameters 6 to pass to java command like my project 5 has about several line of param to pass. So 4 in that case we can use IDE to start application 3 and breaking it to point when we want to 2 debug in native library. Ofcourse native 1 library need to be created in debug mode.

More Related questions