2012-02-13 22 views
11

¿Puede alguien guiarse sobre cómo depurar un código JNI en Linux utilizando el depurador GDB (si es posible, sugiera otras opciones).Cómo depurar Java -JNI usando GDB en Linux?

-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*. 

Tengo el Gdb instalado pero no entiendo cómo podemos depurar el proyecto usándolo. ¿También necesito necesariamente compilar los archivos .cpp con la opción -g t depurar archivos .so?

Respuesta

10
  1. iniciar la aplicación java
  2. Busque el PID usando la parte superior, ps, ...
  3. GDB de inicio con este PID
  4. adjuntar su código de programa
  5. depuración como de costumbre usando GDB

Este blog post lo explica todo.

+4

: encontré otra forma en [link] (http://www2.sys-con.com/itsg/virtualcd/java/archives/0801/austin/index.html). De esta forma, pude depurar el inicio de mi proyecto desde el GDB, por lo que no fue necesario cambiar de shell. –

0

Link por tm.sauron es correcto Pero sería menos conveniente cuando tenemos muchos parámetros para pasar al comando java como mi proyecto tiene varias líneas de param para pasar. Entonces, en ese caso, podemos usar IDE para iniciar la aplicación y dividirla para que señale cuándo queremos depurar en la biblioteca nativa. Por supuesto, la biblioteca nativa debe crearse en modo de depuración.

2

Encontré la siguiente manera realmente interesante. Al vincular el archivo siguiente a la biblioteca jni que desea depurar, cuando la biblioteca es cargada por el enlazador dinámico, inicia automáticamente un gdbserver para el jvm actual, gracias al atributo constructor gcc.

Simplemente usando gdb remoto desde la línea de comandos o desde eclipse, es fácil depurarlo. Solo configuro que si construyo en modo de depuración, no he implementado por el momento para detectar si jvm se inició en la depuración, para permitir esto solo en este momento, pero podría ser fácil.

simplemente adaptado el concepto del artículo aquí: 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 

Además también permite la depuración en dispositivos embebidos con gdbserver instalado y GDB-Multiarch en su PC de desarrollo.

Al depurar desde dentro de eclipse, salta automáticamente entre el depurador de C/C++ y el depurador de Java. Solo tiene que iniciar ambas sesiones de depuración: la de Java y la remota de C/C++ que se ejecuta en 127.0.0.1:11337.

Cuestiones relacionadas