How to Debug Java -JNI using GDB on linux ?

前端 未结 3 1106

Can anyone guide on how to debug a JNI code on Linux using GDB debugger(if possible please suggest other options).

    -My JNI project when running on Linux          


        
相关标签:
3条回答
  • 2020-12-14 03:23
    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 讨论(0)
  • 2020-12-14 03:28

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

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

    I simply adapted the concept from the article 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 on embedded devices with gdbserver installed and gdb-multiarch on your development pc.

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

    0 讨论(0)
  • 2020-12-14 03:42

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

    0 讨论(0)
提交回复
热议问题