2012-07-21 44 views
1

当本地方法调用(直接或间接)某个Linux系统调用时,如何在Java中产生断点?Linux系统调用的Java断点

+0

一个非常奇怪的要求。你能解释一下背景吗?或许可以找到解决问题的其他方法? – 2012-07-21 08:20:07

+0

我想看看我没有编写的任意应用程序,并且方便地确定他们为什么告诉操作系统执行某些操作。我不满意于在Java API调用中放置一个断点,因为可能有多种方法来执行某些操作,而且对于来自定制JNI代码的操作系统调用而言,这些方法根本不起作用。 – 2012-07-21 09:01:26

回答

0

理论上,可以使用Java的提前(AOT)编译器本地编译应用程序,然后使用本地调试器在系统调用上设置断点或catchpoint。 (奖励:然后您将得到一个完整的堆栈跟踪,包括本地方法调用的所有C函数,以及无缝调试这些C函数的能力。)

您可能想要使用调试器,该调试器知道如何取名由AOT编译器生成。例如,gdb知道如何去掉gcj产生的名字,所以gdb的gcj组合应该可以工作。

与之相结合的问题在于,GCJ仍然停留在部分 JDK 1.5的兼容性,并没有被人不屑于做的OpenJDK的类库合并的工作(有人建议在GCJ邮件列表2009)。因此,gcj从未成为流行的选择 - 人们通常会无意中使用它(特别是在Debian和Ubuntu上),但是当它们遇到问题时,他们倾向于转向更标准的JDK,而不是报告错误。

使用AOT编译器进行本地编译也比仅在它认为有必要时让JRE JIT编译代码慢得多。

1

这不是一个断点,但至少它会给你一个堆栈跟踪,这可能是你所需要的。此外,如果需要,Systemtap语言允许您执行更多操作,而不仅仅是打印堆栈跟踪。

在IcedTea JVM源代码中,您会发现一个SystemTap file函数,该函数可用于从正在运行的IcedTea(使用Hotspot)JVM获取堆栈跟踪。据我了解,使用这些函数,您可以从SystemTap支持的任何事件(甚至是来自内核事件)获取Java堆栈跟踪。

请注意,尽管具有相同的名称,但这些jstack函数与JDK提供的jstack(1)命令行实用程序无关。它们通过内存检查工作,而不是通过回调到JVM,因此它们是quite specific to Hotspot internals,因此可能不适用于基于非热点的JVM。

注意:Systemtap does not fully work on default Debian kernels,因此您可能需要在基于Debian的系统上编译自己的内核。这个问题不会影响Fedora或Red Hat。