我想获取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),而不仅仅是汇编代码。
答案 0 :(得分:2)
您不会看到带有gdb backtrace
命令的Java框架。但是,您不需要手动从coredump中提取VM结构 - 有更好的选择。
Serviceability Agent是一种专门用于分析Java进程或coredump内存的工具。它在sa-jdi.jar
中提供Java API,提供标准JDK包。
这是一个example,它使用本地变量信息打印扩展的Java堆栈跟踪。它也可以解析coredumps。
HotSpot JVM的调试版本包括可以从gdb调用的特殊调试函数。 E.g。
psf()
打印堆栈帧; pfl()
打印框架布局; disnm(intptr_t addr)
在给定地址反汇编编译的Java方法; pp(intptr_t addr)
在给定地址打印Java对象; 这些功能在调试活动进程时有效;但不适合coredumps。
BTW,quick guide自己构建JVM的调试版本。