【问题标题】:Race condition in android dlopen()?android dlopen()中的竞争条件?
【发布时间】:2015-12-02 06:05:19
【问题描述】:

我的 Android 应用有一个简单的“加载器”NativeActivity,带有一个非常简单的 android_main(),它只加载不同的共享对象并将控制权传递给它:

typedef void (*Tandroid_main)( android_app*);
void android_main( android_app* state )
{
    void* glib = dlopen("libmain.so", RTLD_NOW);
    void* fmain = dlsym(glib, "android_main");
    Tandroid_main libmain = (Tandroid_main)fmain;
    libmain(state)
}

这很好用.. 大约一半的时间。其他时候它会崩溃,因为dlopen() 失败并返回 NULL 且 errno=2(没有这样的文件)。
由于此事件的奇怪不一致,我怀疑是时间问题,实际上,在dlopen() 之前添加sleep(1) 阻止了它的发生。比sleep(1) 更强大的方法就是循环尝试:

int count = 0;
void* glib = dlopen(soName, RTLD_NOW);
while(glib == NULL) {
    sched_yield();
    ++count;
    glib = dlopen(soName, RTLD_NOW);
}

我从这个循环中获得的计数在我的设备上通常在 10-70 的范围内。但这是一个骇人听闻的丑陋解决方案。

这里到底发生了什么?为什么我只能在 NativeActivity 启动后稍微加载其他共享对象?有没有更好的方法来确定何时可以安全加载?

需要注意的是,我也是从我的 NativeActivity 的onCreate() 调用System.loadLibrary("main")

【问题讨论】:

    标签: android android-ndk race-condition dlopen native-activity


    【解决方案1】:

    不确定,但建议从静态初始化程序调用 loadLibrary():

    public class MainActivity extends Activity {
        static {
            System.loadLibrary("main")
        }
        ...
    }
    

    有帮助吗?

    【讨论】:

      猜你喜欢
      • 2022-12-14
      • 2016-03-07
      • 2011-07-17
      • 2013-02-27
      • 2021-04-16
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多