dlopen определение "та же библиотека" - PullRequest
2 голосов
/ 24 сентября 2019

Согласно справочной странице dlopen (3) :

Если та же библиотека снова загружается с помощью dlopen (), возвращается тот же дескриптор файла.

Что означает «та же библиотека»?То же имя файла?Тот же путь?Тот же инод?То же имя?Что-то другое?Как это поведение взаимодействует с программными ссылками?

Предположим, меня интересуют ELF so и основные дистрибутивы Linux (семейства Debian / Arch / RHEL).

Примеры последствий:

  • Если «одна и та же библиотека» означает «один и тот же SONAME», то я мог бы загрузить один и тот же файл дважды с разными именами и получить только один дескриптор.Если «та же библиотека» означает «то же имя файла», то я, вероятно, получу ужасную путаницу со встречными символами.
  • Если символические ссылки следуют обратно в файл, а «та же библиотека» означает «то же имя файла», то несколько символических ссылокс одним файлом все в порядке, в противном случае, если вместо этого используется имя файла символической ссылки, снова все становится ужасно.
  • Если «одна и та же библиотека» означает «один и тот же путь» и существуют два пути к файлу (например, сжесткие ссылки), вещи беспорядок, иначе, если "та же библиотека" означает "тот же самый inode", все в порядке.

1 Ответ

0 голосов
/ 24 сентября 2019

Я бы сказал, та же библиотека означает тот же путь , я построил небольшой пример для иллюстрации:

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    (void)argc, (void)argv;

    void (*hello)();

    void *handle = dlopen("./libhello.so", RTLD_NOW);
    printf("handle = %p\n", handle);

    void *handle2 = dlopen("libs/libhello.so", RTLD_NOW);
    printf("handle with different path = %p\n", handle2);

    // using symlink to libhello.so
    void *handle3 = dlopen("./symlink.so", RTLD_NOW);
    printf("handle with soft link = %p\n", handle3);

    if (handle == 0) {
        fprintf(stderr, "%s\n", dlerror());
        exit(1);
    }

    void *f = dlsym(handle, "hello");

    if (f) {
        hello = (void (*)())f;
        hello();
    }

    dlclose(handle);

    return 0;
} 

и общую библиотеку:

/* libhello.so */
#include <stdio.h>

void hello()
{
    printf("hello\n");
}

вывод:

handle = 0x217c030
handle with different path = 0x217ca40
handle with soft link = 0x217c030
hello

Надеюсь, это поможет.

...