最近在完善创建jvm的过程,基本上与上次写的《ANDROID上创建DALVIK虚拟机与加载类》一致,此前在测试dalvik及art模式下的时候都没问题的,但最近在使用art模式下创建jvm时去遇到了问题。
使用dlopen打开了libart.so的句柄后,能正常获取到JNI_CreateJavaVM方法,但就是创建不了虚拟机,logcat中提示“InitializeSignalChain is not exported by the main executable.”。大概意思就是InitializeSignalChain没被导出,找不到相关引用的意思吧,第一反应是去找这句提示的出处,最后找到的是在以下地方,代码如下:
1 | // art/sigchainlib/sigchain_dummy.cc |
目测这是最后提示的地方了,提示完就直接abort了,再搜索其他地方,找到/art/runtime/runtime.cc::Init方法,其中有引用到这个方法,发现上述那个只是dummy的错误提示而已,直接的运行代码在/art/sigchainlib/sigchain.cc::InitializeSignalChain。
这里不想探究signalchain是用来干嘛的,搜索后发现一个帖子,一楼跟我的情况基本上是一致的,其中有人提到需要在Android.mk中添加
1 | LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain |
其实目的也是为了把native应用与libsigchain关联,添加后重新编译运行,发现还是同样的问题。
于是我在想是不是一般的机器中libsigchain.so少导出了点什么,于是我在5.1.1的源码中重新把libsigchain.so编译了一次
1 | mmm art/sigchainlib/ |
然后放到机器中重启重新运行,还是一个样子。查看了一下被替换的文件,发现与我编译出来的是一样的(后来想想也对,我也没改动什么,一样也正常)。
到这里本来是想修改源码试试的,但又转念一想,dalvik中存在dalvikvm的可执行程序,可以直接创建vm,在art中是否也存在。很快在art下就找到了dalvikvm的模块了,编译运行一下发现就是这个;接着我再大概看了一下dalvikvm中的代码,与我写的出入是有的,但做法是差不多的,想着既然它能够实现,那么我的应该也行。
于是我就把上文用的CreateVm程序放到了art目录下
接合googld code上的那个帖子,我对我的模块中的Android.mk进行了一点改造(主要都是参考dalvikvm中的Android.mk)
1 | LOCAL_PATH:=${call my-dir} |
其中version-srcipt.txt是从sigchainlib模块中拿的。然后直接
1 | mmm art/jvm_test/ |
后就生成了jvm可执行文件了,放到手机上运行,终于没了错误提示,能够正常创建虚拟机了。