如何在linux上使用GDB调试Java-JNI?
任何人都可以指导如何使用GDB调试器在Linux上调试JNI代码(如果可能,请建议其他选项) 我已经安装了Gdb,但不知道如何使用它调试项目。 我还需要使用-g选项t debug.so文件编译.cpp文件吗如何在linux上使用GDB调试Java-JNI?,java,linux,gdb,java-native-interface,shared-libraries,Java,Linux,Gdb,Java Native Interface,Shared Libraries,任何人都可以指导如何使用GDB调试器在Linux上调试JNI代码(如果可能,请建议其他选项) 我已经安装了Gdb,但不知道如何使用它调试项目。 我还需要使用-g选项t debug.so文件编译.cpp文件吗 启动java应用程序 使用top、ps、…查找pid 使用此pid启动gdb 附上你的程序代码 使用gdb进行常规调试 这篇博客解释了整个过程。by tm.sauron是正确的,但如果我们有许多参数要传递给java命令,那么就不那么方便了,就像我的项目有几行参数要传递一样。所以,在这种情况下
这篇博客解释了整个过程。by tm.sauron是正确的,但如果我们有许多参数要传递给java命令,那么就不那么方便了,就像我的项目有几行参数要传递一样。所以,在这种情况下,我们可以使用IDE启动应用程序,并在需要在本机库中调试时将其中断。当然,本机库需要在调试模式下创建。我发现以下方法非常有趣。通过将下面的文件链接到要调试的jni库,当动态链接器加载该库时,它会自动启动当前jvm的gdbserver,这要归功于gcc构造函数属性 只需从命令行或eclipse使用远程gdb,即可轻松调试。我只是设置如果我在调试模式下构建,我暂时还没有实现来检测jvm是否在调试模式下启动,只允许在此时启动,但这可能很容易 我只是将文章中的概念改写如下:
\ifndef NDEBUG//如果我们正在调试
#包括
#包括
#包括
命名空间调试器{
静态int gdb_进程_pid=0;
/**
*\brief我们通过动态链接器在库加载时创建一个gdb服务器,以便在java开始访问库时能够调试库。
*必须设置断点。
*/
__属性(构造函数)
静态void exec_gdb(){
//创建用于运行GDB调试器的子进程
int-pid=fork();
if(pid<0){
中止();
}否则如果(pid){
//申请过程
gdb_进程\u pid=pid;//保存调试器pid
睡眠(10);/*给GDB时间连接*/
//继续由GDB控制的应用程序执行
}else/*儿童*/{
//GDBServer进程
//将父进程id传递给调试器
std::stringstream-pidStr;
我在找到了另一种方法。通过这种方法,我可以从GDB内部调试启动我的项目,因此它不需要切换不同的shell。
-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*.
#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