如果在本机方法(直接或间接)调用某个Linux系统调用时触发了Java中的断点?
答案 0 :(得分:1)
这不是一个断点,但至少它会给你一个堆栈跟踪,这可能就是你所需要的。此外,如果需要,Systemtap语言允许您执行更多操作,而不仅仅是打印堆栈跟踪。
在IcedTea JVM源代码中,您将找到一个SystemTap file函数,可用于从正在运行的IcedTea(带有Hotspot)JVM获取堆栈跟踪。据我了解,使用这些函数,您可以从SystemTap支持的任何事件中获取Java堆栈跟踪 - 甚至可以从内核事件中获取。
请注意,尽管名称相同,但这些jstack函数与JDK随附的jstack(1)命令行实用程序无关。它们通过内存检查工作,而不是通过回调到JVM,因此它们是quite specific to Hotspot internals,因此可能不适用于非基于Hotspot的JVM。
注意:Systemtap does not fully work on default Debian kernels,因此您可能需要在基于Debian的系统上编译自己的内核。这个问题不会影响Fedora或Red Hat。
答案 1 :(得分:0)
理论上,可以使用Java的提前(AOT)编译器对应用程序进行本机编译,然后使用本机调试器在系统调用上设置断点或捕获点。 (Bonus:然后你会得到一个完整的堆栈跟踪,包括本机方法调用的所有C函数,以及无缝调试这些C函数的能力。)
您可能希望使用一个知道如何解码AOT编译器生成的名称的调试器。例如,gdb知道如何解码由gcj生成的名称,因此gcj与gdb的组合应该可以工作。
这种组合的问题在于gcj仍然坚持部分 JDK 1.5兼容性,并且没有人打扰在OpenJDK类库中进行合并工作(它是在2009年gcj邮件列表)。因此,gcj从来就不是一个受欢迎的选项 - 人们经常无意中使用它(特别是在Debian和Ubuntu上),但是当他们遇到问题时,他们倾向于转换到更标准的JDK而不是报告错误。 / p>
使用AOT编译器进行本机编译也比仅在认为必要时让JRE JIT编译代码慢得多。