Como depurar o Java -JNI usando o GDB no linux?

Alguém pode orientar sobre como depurar um código JNI no Linux usando o depurador GDB (se possível, por favor sugerir outras opções).

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

Eu tenho o Gdb instalado, mas não estou conseguindo como podemos depurar o projeto usando-o. Também preciso necessariamente compilar os arquivos .cpp com a opção -g t debug .so files?

  1. Inicie seu aplicativo java
  2. Olhe para cima o pid usando top, ps, …
  3. Inicie o gdb com este pid
  4. Anexe seu código de programa
  5. Depurar como de costume usando o gdb

Este post do blog explica tudo.

Eu achei o seguinte caminho muito interessante. Ao vincular o arquivo abaixo à biblioteca jni que você deseja depurar, quando a biblioteca for carregada pelo vinculador dynamic, ele inicia automaticamente um gdbserver para o jvm atual, graças ao atributo do construtor gcc.

Basta usar o gdb remoto a partir da linha de comando ou do eclipse para facilitar a debugging. Eu só configurei que se eu construir no modo de debugging, eu não implantei no momento para detectar se o jvm foi iniciado na debugging, para permitir isso apenas neste momento, mas poderia ser fácil.

Eu simplesmente adaptei o conceito do artigo aqui: http://www.codeproject.com/Articles/33249/Debugging-C-Code-from-Java-Application

 #ifndef NDEBUG // If we are debugging #include  #include  #include  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 

Além disso, também permite a debugging em dispositivos incorporados com gdbserver instalado e gdb-multiarch no seu PC de desenvolvimento.

Ao depurar a partir do eclipse, ele salta automaticamente entre o depurador C / C ++ e o depurador Java. Você só precisa iniciar a session de debugging: o java one e o C / C ++ remoto, que é executado em 127.0.0.1:11337.

Link por tm.sauron está certo, mas seria menos conveniente quando temos muitos parâmetros para passar para o comando java como meu projeto tem sobre várias linhas de param para passar. Então, nesse caso, podemos usar o IDE para iniciar o aplicativo e dividi-lo para apontar quando quisermos depurar na biblioteca nativa. A biblioteca nativa do Ofcourse precisa ser criada no modo de debugging.

Intereting Posts