TGViewer
LinuxCamp | DevOps LinuxCamp | DevOps @linuxcamp_tg · 13.6K subscribers
Post #47 3.81K
Использование флага компоновщика -Bsymbolic

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

Допустим, у нас есть главная программа и разделяемая библиотека, и в обеих определена глобальная функция хуz(), которая вызывается из другой библиотечной функции:


// Выводим содержимое main.c
$ cat ./main.c
void xyz(){
printf("main-xyz");
}

void main(){
func();
}

// Выводим содержимое libdemo.c
$ cat libdemo.c
void xyz(){
printf("libdemo-xyz");
}

void func(){
xyz();
}


Собрав разделяемую библиотеку и исполняемый файл и затем запустив полученную программу, мы увидим следующее:


$ gcc -g -c -fPIC -Wall -c libdemo.c
$ gcc -g -shared -o libdemo.so libdemo.o
$ gcc -g -o prog main.c libdemo.so
$ LD_LIBRARY_PATH=./ ./prog

main-xyz


В последней строчке мы видим, что определение хуz() из главной программы переопределяет (перекрывает) одноименную функцию в разделяемой библиотеке.

Главная проблема такого механизма - несовместимость с принципом, согласно которому разделяемая библиотека должна быть реализована в качестве самодостаточной подсистемы. В результате такого подхода, разделяемая библиотека не гарантирует, что ссылка на один из ее собственных глобальных символов будет привязана к ее же определению этого символа.

Следовательно, свойства библиотеки могут измениться при включении ее в более крупный модуль. Это может привести к непредвиденным сбоям в приложении и усложнить раздельную отладку (например, когда вы пытаетесь воспроизвести проблему, используя другие разделяемые библиотеки или уменьшая их количество).

Для гарантии того, что в вышеописанном сценарии вызов хуz() в разделяемой библиотеке приведет к запуску именно той функции, которая в ней определена, на этапе сборки компоновщику можно передать параметр -Bsymbolic:


$ gcc -g -c -fPIC -Wall -c libdemo.c
$ gcc -g -shared -Wl,-Bsymbolic -o libdemo.so libdemo.c
$ gcc -g -o prog main.c libdemo.so
$ LD_LIBRARY_PATH=./ ./prog

libdemo-xyz


Параметр компоновщика -Bsymbolic делает так, что ссылки на глобальный символ внутри разделяемой библиотеки в первую очередь должны привязываться к определению из этой библиотеки (если таковое существует).

Стоит отметить: вне зависимости от данного параметра, вызов хуz() главной программы всегда приводит к запуску той версии функции, которая в ней определена.
  • 👍 9
  • 🔥 7
  • ❤‍🔥 2
More from @linuxcamp_tg
  1. Oct 9, 2026🤖Обходим «белый список» вместе с STRELKA Думали, что белые списки не обходятся когда глуш…
  2. Sep 28, 2026Проекту GNU вчера исполнилось 43 года 1983 год: Ричард Столлман объявил планы разработать…
  3. Sep 25, 2026Linux будет работать на ноутах с Snapdragon X2. Qualcomm добавляет полноценную поддержку L…
  4. Sep 24, 2026Так все по делу)) Советует же самый быстрый фикс LinuxCamp | #memes
  5. Sep 23, 2026Планы на 3 октября — прийти на RWB Infra x Security Meetup Мы направим прожекторы на инфра…
  6. Sep 22, 2026Ещё одна рекордная неделя для AI-разработки в Linux. На прошлой неделе в ядро попало 1 634…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →