美文网首页
进程重复加载库问题

进程重复加载库问题

作者: Little熊猫 | 来源:发表于2019-03-01 13:53 被阅读0次

一 问题概述

同一个库能不能被多个进程多次加载? 答案是it depends.让我们看看几种被多次加载的情况。
example 1:

//libtest.a
static char *a[10];
int a_set(int index, char value) {
     
}
int a_unset(int index) {

}

显然如果libA(static link)-->libtest libB(static link)-->libtest,对于程序test依赖于libA和libB,那么libtest.a会被重复加载两次。在某种情况下,调用的是libA加载的a_set,而a_unset调用的是libB的,那么会造成结果不一致或者其他类问题。因此像libtest.a这种程序不能被同一个进程重复加载。
如果像下面这种函数的话

libtest_1.a
void a_set(char *array, int idex, char value) {
    array[idex] = value;
} 
void a_unset(char *array, int dex) {
    array[index] = 0;
}

上面这种函数及时被同一个进程多次加载也不会有问题。
因此一个so或者a能否被同一个进程多次加载,这个视情况而定,有的可以有的不可以

二 android下库被多次加载问题

从android 8.1 treble开启之后,谷歌自行对这样的库有过一次分类,在/system/lib/vndk-sp下的库是可以被重复加载的,这些都是经过谷歌验证的。同一进程多次加载没有问题。
像这种基础库,被多次加载一般都有什么问题呢? 以libc++.so为例,总结大体如下:
libc++有c++_static和c++_shared两种库

 Application.mk
 APP_STL := c++_static

 # Android.mk

 include $(CLEAR_VARS)
 LOCAL_MODULE := foo
 LOCAL_SRC_FILES := foo.cpp
 include $(BUILD_SHARED_LIBRARY)

 include $(CLEAR_VARS)
 LOCAL_MODULE := bar
 LOCAL_SRC_FILES := bar.cpp
 LOCAL_SHARED_LIBRARIES := foo
 include $(BUILD_SHARED_LIBRARY)

如果一个进程同时依赖libbar.so和libfoo.so,那么c++_static.a将被进程加载两次。有可能会遇到如下几类问题:
1) 如果内存是在bar.so分配在foo.so释放的话,会造成memleak或者堆crash
2) 如果是bar.so抛出的异常被foo.so扑获的话,造成app crash
3) std::cout缓存问题
现在谷歌在ndk开发中只能使用libc++.so之前使用的libstdc++.so将不被允许,但是可能有些老的库是依赖libstdc++.so的,那么一个app是否可以同时依赖libc++.so和libstdc++.so呢?答案是否定的。原因如下:
像std::string这中函数在这两个库中的定义是不一样的,如果string操作跨STL操作的话,会出现问题。这种情况同上面静态库多次加载情况也一样。

三 总结

因此对于一个库被重复加载的情况下,这个看情况而定,如果不是使用同一个STL标准的话,需要先统一标准c++后再进行编译。

相关文章

网友评论

      本文标题:进程重复加载库问题

      本文链接:https://www.haomeiwen.com/subject/grdduqtx.html