dlopen () в многопоточном приложении завершается с "Trace / BPT trap" - PullRequest
1 голос
/ 05 января 2012

Я пытаюсь загрузить фреймворк во время выполнения в приложении Mac OS X, написанном на C, с помощью следующей команды:

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;
}

Вывод: библиотека JavaVM загружена

Это код, который вызывает 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 trap

Где ошибка?Извините, если это глупый вопрос, но я все еще новичок

1 Ответ

1 голос
/ 05 января 2012

Кажется, что dlopen () не является поточно-ориентированным, поэтому не следует вызывать его в нескольких потоках.
Или, возможно, это не dlopen (), который не является поточно-ориентированным, нокод инициализации вашей библиотеки, который запускается при загрузке.

Нет причин вызывать dlopen для потоков, поскольку он не будет загружать библиотеку несколько раз.
Когда вы загружаете один и тот же файл несколько раз, товторой раз ничего не делает (кроме увеличения некоторого refcount) и просто возвращает тот же дескриптор.Таким образом, вы ничего не получаете, загружая его на каждый поток.

Вы можете использовать dlmopen (), чтобы действительно загрузить библиотеку несколько раз.Но это ограничено 15 разами.
И даже в этом случае вы должны сделать это в main () перед запуском потоков (и дать каждому потоку свой дескриптор библиотеки), а не из потока.

...