我是靠谱客的博主 繁荣百合,最近开发中收集的这篇文章主要介绍编译32位windows系统下可用的JVMTI动态链接库一.环境搭建二.工具使用三.遇到的问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

        这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++编写的动态共享库。

 linuxwindowsmac
目标文件.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动态链接库一.环境搭建二.工具使用三.遇到的问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部