Поиск символов в общих библиотеках

Я проверил такую ​​простую программу ниже

/* a shared library */
dispatch_write_hello(void)
{
        fprintf(stderr, "hello\n");
}

extern void
print_hello(void)
{
        dispatch_write_hello();
}

Моя основная программа такая:

extern void
dispatch_write_hello(void)
{
        fprintf(stderr, "overridden\n");
}

int
main(int argc, char **argv)
{
        print_hello();
        return 0;
}

Результат программы "переопределен".
Чтобы понять, почему это происходит, я использовал gdb. Цепочка вызовов выглядит так:
_dl_runtime_resolve -> _dl_fixup ->_dl_lookup_symbol_x
Я нашел определение _dl_lookup_symbol_x в glibc есть

Поиск в таблицах символов загруженных объектов для определения символа UNDEF_NAME, возможно, с запрошенной версией для символа

Вот и думаю при попытке найти символ dispatch_write_helloсначала он ищет в главном объектном файле, а затем в общей библиотеке. Это причина этой проблемы. Правильно ли мое понимание? Большое спасибо за ваше время.

1 ответ

Решение

Учитывая, что вы упоминаете _dl_runtime_resolveЯ предполагаю, что вы работаете в системе Linux (спасибо @Olaf за разъяснения).

Короткий ответ на ваш вопрос - да, во время вставки символов динамический компоновщик сначала заглядывает внутрь исполняемого файла, а затем сканирует общие библиотеки. Так определение dispatch_write_hello будет преобладать.

РЕДАКТИРОВАТЬ

В случае, если вам интересно, почему компоновщик времени выполнения должен разрешить вызов dispatch_write_hello в print_hello к чему-либо кроме dispatch_write_hello в той же единице перевода - это вызвано так называемой поддержкой семантической вставки в GCC. По умолчанию компилятор обрабатывает любой вызов внутри библиотечного кода (т. Е. Кода, скомпилированного с -fPIC) как потенциально вставляемый во время выполнения, если вы не указали это -fvisibility-hidden, -Wl,-Bsymbolic, -fno-semantic-interposition или же __attribute__((visibility("hidden"))), Это обсуждалось в сети много раз, например, в печально известном состоянии "Извините" динамических библиотек в Linux.

Напомним, что эта функция значительно снижает производительность по сравнению с другими компиляторами (Clang, Visual Studio).

Другие вопросы по тегам