我想获取jitted代码的汇编代码,以根据Java调用约定获取参数值。 假设 JVM 是热点,平台是 Linux 64 位,我们有以下调用者和被调用者,我想检查从 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++方法,我们可以顺便使用gdb,通过命令 backtrace 打印调用堆栈,然后帧N(N是线程号),然后 x/20i $pc-64 得到汇编代码,我们可以从相关的框架上下文寄存器中获取值。 但是Java方法调用栈无法从gdb中打印出来,而且我们不知道帧号,那么我们就不能像c/c++一样获取汇编代码,那么如何查看Java的汇编代码呢?来自核心转储的 jitted 方法?
PS, 有人提到了 PrintOptoAssembly,但是我需要汇编代码通过调用约定(例如通过 backtrace ,然后是frame N ,然后通过 gdb x/20i $pc-64 )从寄存器获取参数值,而不仅仅是汇编代码。最佳答案
使用 gdb backtrace
命令您不会看到 Java 帧。但是,您不需要手动从核心转储中提取虚拟机结构 - 有更好的选择。
1。热点服务能力代理
Serviceability Agent是专门为分析Java进程内存或核心转储而设计的工具。它有Java API可在标准 JDK 包提供的 sa-jdi.jar
中找到。
这是一个example打印带有局部变量信息的扩展 Java 堆栈跟踪。它还可以解析核心转储。
2。 HotSpot调试功能
HotSpot JVM 的调试版本包括可以从 gdb 调用的特殊调试函数。例如
psf()
打印堆栈帧;pfl()
打印框架布局;disnm(intptr_t addr)
在给定地址反汇编已编译的 Java 方法;pp(intptr_t addr)
在给定地址打印 Java 对象;- 等等。请参阅 debug.cpp 中的其他命令.
这些函数在调试 Activity 进程时起作用;但不适合核心转储。
顺便说一句,一个quick guide自己构建JVM的调试版本。
关于java - 如何通过汇编代码从 JVM 核心转储中检查 jitted Java 方法参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41715532/