android dlopen() 中的竞争条件?
Race condition in android dlopen()?
我的 Android 应用程序有一个简单的 "loader" 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()
失败并且 return NULL with errno=2 (No such file).
由于这种情况奇怪的不一致,我怀疑是时间问题,实际上,在 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")
不确定,但建议从静态初始化程序调用 loadLibrary():
public class MainActivity extends Activity {
static {
System.loadLibrary("main")
}
...
}
有帮助吗?
我的 Android 应用程序有一个简单的 "loader" 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()
失败并且 return NULL with errno=2 (No such file).
由于这种情况奇怪的不一致,我怀疑是时间问题,实际上,在 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")
不确定,但建议从静态初始化程序调用 loadLibrary():
public class MainActivity extends Activity {
static {
System.loadLibrary("main")
}
...
}
有帮助吗?