Поиск символов в общих библиотеках
Я проверил такую простую программу ниже
/* 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).