如何通过汇编代码检查JVM核心转储中的jitted Java方法参数?

时间:2017-01-18 09:23:56

标签: java jvm gdb

我想获取jitted代码的汇编代码,以根据Java调用约定获取参数值。 假设JVM是热点,平台是Linux 64位,我们有以下调用者和calle,我想检查从JVM核心转储传递给被调用者的参数。

protected void caller( ) {
callee(1,"123", 123,1);

}

protected void callee(int a,String b, Integer c,Object d) {
 Thread.sleep(11111111);
}

基于以下Java调用约定,我们知道我们可以从寄存器中获取参数,例如寄存器中最多传递6个第一个整数参数:rsi,rdx,rcx,r8,r9,rdi http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/b4bdf3484720/src/cpu/x86/vm/assembler_x86.hpp#l91

对于c / c ++方法,我们可以通过命令backtrace打印调用堆栈的方式使用gdb,然后是帧N(N是线程号),然后是x / 20i $ pc-64来获取汇编代码,我们可以从相关的帧上下文寄存器中获取值。 但是无法从gdb打印Java方法调用堆栈,并且我们不知道帧编号,那么我们不能像c / c ++那样使用相同的方式来获取汇编代码,那么如何检查汇编代码来自核心转储的Java jitted方法?

PS, 有人提到了PrintOptoAssembly,但我需要汇编代码通过调用约定来获取寄存器中的参数值(例如通过回溯,然后是帧N,然后是x / 20i $ pc-64到gdb),而不仅仅是汇编代码。

1 个答案:

答案 0 :(得分:2)

您不会看到带有gdb backtrace命令的Java框架。但是,您不需要手动从coredump中提取VM结构 - 有更好的选择。

1。 HotSpot可维护性代理

Serviceability Agent是一种专门用于分析Java进程或coredump内存的工具。它在sa-jdi.jar中提供Java API,提供标准JDK包。

这是一个example,它使用本地变量信息打印扩展的Java堆栈跟踪。它也可以解析coredumps。

2。 HotSpot调试功能

HotSpot JVM的调试版本包括可以从gdb调用的特殊调试函数。 E.g。

  • psf()打印堆栈帧;
  • pfl()打印框架布局;
  • disnm(intptr_t addr)在给定地址反汇编编译的Java方法;
  • pp(intptr_t addr)在给定地址打印Java对象;
  • 等。请参阅debug.cpp中的其他命令。

这些功能在调试活动进程时有效;但不适合coredumps。

BTW,quick guide自己构建JVM的调试版本。