ass*_*ias 73
如其他答案所述,您可以使用以下JVM选项运行:
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
Run Code Online (Sandbox Code Playgroud)
您还可以使用以下语法过滤特定方法:
-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod
Run Code Online (Sandbox Code Playgroud)
笔记:
如果您运行的是Windows,则此页面包含有关如何构建和安装hsdis-amd64.dll
以及hsdis-i386.dll
使其工作所需的说明.我们在下面复制并扩展该页面的内容*以供参考:
哪里可以获得预建的二进制文件
您可以从fcml项目下载Windows的预构建二进制文件
如何建立hsdis-amd64.dll
和hsdis-i386.dll
在Windows
此版本的指南是使用64位Cygwin在Windows 8.1 64位上编写的,并生成hsdis-amd64.dll
安装Cygwin.在Select Packages
屏幕上,添加以下包(通过展开Devel
类别,然后在Skip
每个包名旁边的标签上单击一次):
make
mingw64-x86_64-gcc-core
(只需要hsdis-amd64.dll
)mingw64-i686-gcc-core
(只需要hsdis-i386.dll
)diffutils
(在Utils
类别中)运行Cygwin终端.这可以使用安装程序创建的桌面或开始菜单图标来完成,并将创建您的Cygwin主目录(C:\cygwin\home\<username>\
或C:\cygwin64\home\<username>\
默认情况下).
binutils-2.25.tar.bz2
.这应该会导致binutils-2.25
Cygwin主目录中名为(或最新版本)的目录.src\share\tools
)解压缩到Cygwin主目录.cd ~/hsdis
.要建立hsdis-amd64.dll
,请输入
make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25
要建立hsdis-i386.dll
,请输入
make OS=Linux MINGW=i686-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25
在任何一种情况下,请替换2.25
您下载的binutils版本.OS=Linux
是必要的,因为虽然Cygwin是一个类似Linux的环境,但hsdis makefile无法识别它.
./chew: No such file or directory
和gcc: command not found
.编辑<Cygwin home directory>\hsdis\build\Linux-amd64\bfd\Makefile
在像写字板或记事本的文本编辑器++改变SUBDIRS = doc po
(线342,如果使用的binutils 2.25)到SUBDIRS = po
.重新运行上一个命令.该DLL现在可以通过从复制它被安装hsdis\build\Linux-amd64
或hsdis\build\Linux-i586
您的JRE bin\server
或bin\client
目录.您可以通过搜索找到系统上的所有此类目录java.dll
.
额外提示:如果您更喜欢AT&T的英特尔ASM语法,请指定-XX:PrintAssemblyOptions=intel
您使用的任何其他PrintAssembly选项.
*页面许可证是Creative Commons
Fal*_*ina 45
假设您正在使用Sun Hotspot JVM(即Oracle 提供的java.com上的JVM ),您可以添加标志
-XX:+ PrintOptoAssembly
在运行代码时.这将打印出JIT编译器生成的优化代码,并将其余部分排除在外.
如果要查看整个字节码,包括未经优化的部分,请添加
-XX:CompileThreshold =#
当你运行你的代码时.
您可以在此处阅读有关此命令和JIT功能的更多信息.
swo*_*iak 28
您需要一个hsdis插件才能使用PrintAssembly
.一个方便的选择是基于FCML库的hsdis插件.
它可以为类UNIX系统编译,在Windows上,您可以使用Sourceforge上的FCML 下载部分中提供的预构建库:
java.dll
(使用Windows搜索).在我的系统上,我在两个位置找到它:
C:\Program Files\Java\jre1.8.0_45\bin\server
C:\Program Files\Java\jdk1.8.0_45\jre\bin\server
cd <source code dir>
./configure && make && sudo make install
cd example/hsdis && make && sudo make install
sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/lib/amd64/hsdis-amd64.so
sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/jre/lib/amd64/hsdis-amd64.so
/usr/lib/jvm/java-8-oracle
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
-XX:+LogCompilation -XX:PrintAssemblyOptions=intel,mpad=10,cpad=10,code
-jar fcml-test.jar
Run Code Online (Sandbox Code Playgroud)
其他配置参数:
代码在助记符之前打印机器代码.
intel使用Intel语法.
gas使用AT&T汇编语法(兼容GNU汇编程序).
dec将 IMM和位移打印为十进制值.
mpad = XX填充指令的助记符部分.
cpad = XX填充机器代码.
seg显示默认的段寄存器.
零在HEX文字的情况下显示前导零.
对于Windows,Intel语法是默认语法,而AT&T语言是GNU/Linux的默认语法.
有关更多详细信息,请参阅" FCML库参考手册"
小智 8
对于HotSpot(是Sun)JVM,即使在产品模式下:
http://wikis.oracle.com/display/HotSpotInternals/PrintAssembly
需要一些程序集:它需要一个插件.
我相信如果你在Windows机器上运行WinDbg会有所帮助.我刚跑了一个罐子.
通过kb查看未受损的callstack,有:
0008fba8 7c90e9c0 NTDLL!KiFastSystemCallRet
0008fbac 7c8025cb NTDLL!ZwWaitForSingleObject + 0xC的
0008fc10 7c802532 KERNEL32!WaitForSingleObjectEx + 0xa8
0008fc24 00403a13 KERNEL32!WaitForSingleObject的+ 0×12
0008fc40 00402f68的java + 0x3a13
0008fee4 004087b8的java + 0x2f68
0008ffc0 7c816fd7的java + 0x87b8
0008fff0 00000000 KERNEL32!BaseProcessStart + 0×23
突出显示的行是在JVM上直接运行JIT编码.
然后我们可以查找方法地址:
java + 0x2f68是00402f68
在WinDBG上:
单击"查看" - >"反汇编".
单击编辑 - >转到地址.
把00402f68放在那里
得到
00402f68 55 push ebp
00402f69 8bec mov ebp,esp
00402f6b 81ec80020000 sub esp,280h
00402f71 53 push ebx
00402f72 56 push esi
00402f73 57 push edi
...依此类推
有关其他信息,请参阅示例如何使用process explorer和WinDbg从内存转储中追溯JIT-ed代码.
归档时间: |
|
查看次数: |
16945 次 |
最近记录: |