概述
这3天研究如何编译32位windows系统下可用的jVMTI动态链接库。中间过程很多时间都在搭建各种环境,其他时间在学习编译和各个系统的相关知识,总的来说,受益匪浅。记录一下3天踩过的坑和解决方法。
JVM TI是JDK提供的一套用于开发JVM监控, 问题定位与性能调优工具的通用编程接口(API)。通过JVMTI,我们可以开发各式各样的JVMTI Agent。这个Agent的表现形式是一个以c/c++语言编写的动态共享库。
JVMTI Agent原理: java启动或运行时,动态加载一个外部基于JVM TI编写的dynamic module到Java进程内,然后触发JVM源生线程Attach Listener来执行这个dynamic module的回调函数。在函数体内,你可以获取各种各样的VM级信息,注册感兴趣的VM事件,甚至控制VM的行为。
我们要做的就是编译这个c/c++编写的动态共享库。
linux | windows | mac | |
---|---|---|---|
目标文件 | .o | .obj | .o |
静态共享库 | .a | .lib | .a |
动态共享库 | .so | .dll | .dylib |
参考gcc编译参数学习gcc编译过程
一个C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)、和连接(linking)才能变成可执行文件。
一.环境搭建
1.本地demo
该demo是通过attach api,这是一套纯java的api,它负责动态地将dynamic module attach到指定进程id的java进程内并触发回调。开发一个JVMTI agent。
通过git clone代码后,打开项目,下载maven包。使用自带gcc编译包后,放到resource文件夹下,修改参数loadAgentPath路径为自己新编译的动态链接库,便可以跑通本地demo.
2.windows7 32bit
因为目标是编译在win7 32位机器上运行的动态链接库,所以需要安装一个32位的win7虚拟机,我用的是vmware,这里要注意你的mac版本和vmware的版本是否匹配。同时安装win7镜像的时候不要安装ghost镜像。和本地demo一样,将编译好的dll文件放在resource下,修改参数loadAgentPath路径为自己新编译的动态链接库。
3.ubunto16.04
需要一个linux环境进行交叉编译,我选择了ubunto,教程自行百度。
二.工具使用
1.vmware vmtools
mac上一款优秀的虚拟机软件,vmtools是用来在本机和虚拟机进行文件拷贝和解决全屏等问题的插件。
2.MinGW
交叉编译工具,安装在ubunto下,安装成功后可以自行选择32还是64位进行编译。
生成ForceFGC.o文件
i586-mingw32-gcc -c -DBUILD_DLL ForceGC.c
生成ForceGC.dll文件
i586-mingw32-gcc -shared -o ForceGC.dll ForceGC.o -Wl,--kill-at,--out-implib,libForceGC.a
3.自带gcc
可以进行linux下的动态库编译
生成ForceGC.o文件
gcc -shared -fPIC -c ForceGC.c -I /usr/lib/jvm/jdk1.8.0_171/include/ -I /usr/lib/jvm/jdk1.8.0_171/include/linux
生成ForceGC.so文件
gcc -shared -fPIC -o ForceGC.so ForceGC.o
4.arm-linux-gcc
可以进行不同cpu架构下的交叉编译,使用Linux主机编写的,然后编译后要在ARM上运行的可执行文件。多用在嵌入式机器上。
三.遇到的问题
1.windows的命名
碰到一个很坑的问题,在此记录一下。因为在windows中报了一个错有可能是文件没有找到造成的,所以我自己做了个实验。建了一个1.txt的txt文件,然后读取他,却一直报这个文件系统找不到,一开始以为是虚拟机的存储系统造成的问题,后来把这个文件的路径打出来也没问题,最后打出整个的全称发现,这个文件名是1.txt.txt。然而报错并不是没有找到系统文件。gettempdir()误导了我。。真正的原因是下面一条。
2.生成环境下的com.sun.tools不会自己引入,且windows版本的包和linux版本的包不一样
一个开始报错attach的classnotfound。在windows环境下,tools包不会自己引入,和在mac不一样,需要自己手动引入,我后来把mac上的tools下载了一份拷贝过去手动链接,报了另一个醋,就是java.lang.UnsatisfiedLinkError: sun.tools.attach.BsdVirtualMachine.getTempDir()Ljava/lang/String;我以为是系统文件没有找到的错。然而是因为windows下的tools包和linux下的包不一样,我又下了windows的包,重新引入错误解决。这里加上system最好。
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.6.0</version>
<scope>system</scope>
<systemPath>D:/Java/jdk1.6.0_27/lib/tools.jar</systemPath>
</dependency>
3.虚拟机vm显示打不开 /dev/vmmon:无此文件或目录
可以按下列步骤解决:
1. 退出VMware fusion;
2. 打开终端;
3. 执行命令:sudo rm -rf /System/Library/Extensions/vmmon.kext ,根据提示输入管理员密码;
4. 执行命令:sudo cp -pR /Applications/VMware Fusion.app/Contents/Library/kexts/vmmon.kext /System/Library/Extensions/
5. 执行命令:sudo kextutil /System/Library/Extensions/vmmon.kext
6. Quit Terminal 如果出现执行第五步报错,可以尝试先执行下面的命令: sudo kextunload /System/Library/Extensions/vmmon.kext 如果不出现Failed to unload com.vmware.kext.vmx86 - (libkern/kext) kext (kmod) start/stop routine failed,恭喜你可以执行第五步命令了,如果出现了,可以先尝试重启机器后再执行上述步骤。
4.ubunto下的apt-get MinGW安装问题
软件包找不到的问题,换源,在下载。前面如果不行则手动加入源
5.arm-linux-gcc的包
找了半天都没找到可以免费下载的包,就不浪费这个时间了,上淘宝花了2块下载的包。虽然这次最终没有用到,但还是比较好用的包。安装使用教程度娘。
6.vmtools安装问题
无法 mkdir: 只读文件系统”解决办法
最后
以上就是繁荣百合为你收集整理的编译32位windows系统下可用的JVMTI动态链接库一.环境搭建二.工具使用三.遇到的问题的全部内容,希望文章能够帮你解决编译32位windows系统下可用的JVMTI动态链接库一.环境搭建二.工具使用三.遇到的问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复