任何人都可以指导如何使用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选项t debug .so文件编译.cpp文件吗?
答案 0 :(得分:12)
此博客post解释了整个事情。
答案 1 :(得分:2)
我发现以下方式非常有趣。通过将下面的文件链接到您要调试的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和gdb-multiarch的嵌入式设备上进行调试。
在eclipse中进行调试时,它会在C / C ++调试器和Java调试器之间自动跳转。您只需要启动两个调试会话:java one和远程C / C ++,它运行在127.0.0.1:11337。
答案 2 :(得分:0)
Link是正确的但是当我们有许多参数传递给java命令时会不太方便,就像我的项目有几行param要传递一样。因此,在这种情况下,我们可以使用IDE启动应用程序,并在我们想要在本机库中进行调试时将其分解。需要在调试模式下创建Ofcourse本机库。