我发现以下方式非常有趣。通过将下面的文件链接到要调试的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 的嵌入式设备上进行调试,并在开发 pc 上调试 gdb-multiarch。
从 eclipse 内部进行调试时,它会在 C/C++ 调试器和 Java 调试器之间自动跳转。您只需要启动两个调试会话:java会话和远程C / C++会话,该会话在127.0.0.1:11337上运行。