【问题标题】:dlopen() in multithreaded application exit with "Trace/BPT trap"多线程应用程序退出中的 dlopen() 带有“Trace/BPT 陷阱”
【发布时间】:2012-01-05 15:01:18
【问题描述】:

我正在尝试在运行时使用以下命令在用 C 编写的 Mac OS X 应用程序中加载框架:

dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM",RTLD_LAZY);

如果我从主线程调用dlopen(),它会按预期工作。

当我从另一个线程调用它时,应用程序退出并出现错误:Trace/BPT trap

这是从主线程调用dlopen()的代码(并且有效):

int main(int argc, char** argv)
{

    void *result = dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM",RTLD_LAZY);
    if (!result) {
        printf("can't open library JavaVM: %s\n", dlerror());
    }
    else {
        printf("library JavaVM loaded\n");
    }

    return 0;
}

输出是:library JavaVM loaded

这是从另一个线程调用dlopen() 的代码(并在调用该函数期间退出):

void *loadJava(void* arg)
{
    void *result = dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM",RTLD_LAZY);
    if (!result) {
        printf("can't open library JavaVM: %s\n", dlerror());
    }
    else {
        printf("library JavaVM loaded\n");
    }
}

int main(int argc, char** argv)
{
    pthread_t vmthread;

    struct rlimit limit;
    size_t stack_size = 0;
    int rc = getrlimit(RLIMIT_STACK, &limit);
    if (rc == 0) {
        if (limit.rlim_cur != 0LL) {
            stack_size = (size_t)limit.rlim_cur;
        }
    }

    pthread_attr_t thread_attr;
    pthread_attr_init(&thread_attr);
    pthread_attr_setscope(&thread_attr, PTHREAD_SCOPE_SYSTEM);
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
    if (stack_size > 0) {
        pthread_attr_setstacksize(&thread_attr, stack_size);
    }

    pthread_create(&vmthread, &thread_attr, loadJava, NULL);
    pthread_attr_destroy(&thread_attr);

    pthread_exit(NULL);

    return 0;
}

输出为:Trace/BPT 陷阱

错在哪里? 对不起,如果这是一个愚蠢的问题,但我还是个新手

【问题讨论】:

  • 作为评论而不是答案发布,因为我不是 100% 确定这一点,但我很确定 JVM 期望在主线程上初始化,否则将无法工作.一旦它启动,它就会创建许多自己的线程,并对其环境做出许多假设,其中可能包括在原始线程上启动。如果有人能提供一个有效的反例,我很乐意撤回我的主张。
  • @ErnestFriedman-Hill 谢谢你的回答。在this Apple 技术说明中写道: 将 JVM 嵌入到本地 Mac OS X 应用程序与其他平台有一个主要区别:如果使用 AWT,JVM 不能在应用程序的主线程上启动。许多教程和文档在主线程上启动 JVM,因此认识到 Mac OS X 的这一独特要求很重要。由于需要使用AWT,所以需要在另一个线程上启动JVM。

标签: c multithreading trace dlopen


【解决方案1】:

dlopen() 似乎不是线程安全的,所以你不应该在多个线程下调用它。
或者,不是线程安全的不是 dlopen(),而是加载时运行的库的初始化代码。

没有理由在线程下调用 dlopen,因为它不会多次加载库。
当您多次加载同一个文件时,第二次什么也不做(除了增加一些引用计数),只返回相同的句柄。因此,通过按线程加载它,您将一无所获。

您可以使用 dlmopen() 多次真正加载库。但仅限于 15 次。
即使这样,您也应该在启动线程之前在 main() 中执行此操作(并为每个线程提供其库句柄),而不是在线程内部。

【讨论】:

  • 谢谢!我在主线程中使用了 dlopen() ,然后将句柄传递给新创建的线程。它现在按预期工作。
  • 顺便说一句,如果您尝试在多线程上下文中使用lt_dlopen libtool 包装器调用,也会出现这种情况。
猜你喜欢
  • 2013-06-02
  • 2014-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-06
  • 1970-01-01
  • 2018-08-31
相关资源
最近更新 更多