Статическая линковка Linux мертва?

Фактически, флаг -static gcc в Linux сейчас не работает. Приведу цитату из FAQ по GNU libc:

2.22. Даже статически скомпонованные программы нуждаются в некоторых разделяемых библиотеках, что для меня неприемлемо. Что я могу сделать?

{AJ} NSS (для получения подробной информации просто введите `info libc" Name Service Switch ") не будет работать должным образом без разделяемых библиотек. NSS позволяет использовать различные службы (например, NIS, files, db, hesiod), просто изменяя один файл конфигурации (/etc/nsswitch.conf) без повторного связывания каких-либо программ. Единственный недостаток заключается в том, что теперь статическим библиотекам требуется доступ к разделяемым библиотекам. Это прозрачно обрабатывается библиотекой GNU C.

Решение - настроить glibc с помощью --enable-static-nss. В этом случае вы можете создать статический двоичный файл, который будет использовать только dns и файлы служб (для этого измените /etc/nsswitch.conf). Вам необходимо явно указать ссылку на все эти службы. Например:

 gcc -static test-netdb.c -o test-netdb \
   -Wl,--start-group -lc -lnss_files -lnss_dns -lresolv -Wl,--end-group

Проблема с этим подходом заключается в том, что вам нужно связать каждую статическую программу, которая использует подпрограммы NSS, со всеми этими библиотеками.
{UD} Фактически, больше нельзя сказать, что libc, скомпилированная с этой опцией, использует НСС. Переключателя больше нет. Поэтому настоятельно рекомендуется не использовать --enable-static-nss, поскольку это делает поведение программ в системе несовместимым.

Что касается этого факта, есть ли какой-нибудь разумный способ создать полнофункциональную статическую сборку в Linux или статическая компоновка полностью мертва в Linux? Я имею в виду статическую сборку, которая:

  • Ведет себя точно так же, как и динамическая сборка (static-nss с непоследовательным поведением - зло!);
  • Работает на разумных вариациях среды glibc и версий Linux;

person Shcheklein    schedule 07.08.2010    source источник
comment
Подходит ли для ваших целей никакая другая замена библиотеки C? (диета / uclibc / и т. д.)?   -  person Tim Post♦    schedule 07.08.2010
comment
Они используют NSS? Скорее всего, поведение тоже будет непоследовательным, так как я сомневаюсь, что эти библиотеки учитывают NSS.   -  person Shcheklein    schedule 07.08.2010
comment
Вы даже используете какие-либо функции, которые в конечном итоге заканчиваются вызовом nss (например, gethostname / getpwname / getgroups / и т. Д.)?   -  person nos    schedule 07.08.2010
comment
Конечно)) Это приложение клиент / сервер.   -  person Shcheklein    schedule 07.08.2010
comment
Это все еще так, или все изменилось с 2010 года?   -  person Atifm    schedule 18.07.2016
comment
ознакомьтесь с статическим Linux   -  person osvein    schedule 07.10.2017


Ответы (6)


Что касается этого факта, есть ли какой-нибудь разумный способ создать полнофункциональную статическую сборку в Linux или статическая компоновка полностью мертва в Linux?

Я не знаю, где найти исторические ссылки, но да, статическое связывание не работает в системах GNU . (Я считаю, что он умер при переходе с libc4 / libc5 на libc6 / glibc 2.x.)

Функция была признана бесполезной в связи с:

  • Уязвимости в системе безопасности. Приложение, которое было статически связано, даже не поддерживает обновление libc. Если приложение было связано с системой, содержащей уязвимость библиотеки, то оно будет сохранено в статически связанном исполняемом файле.

  • Раздутие кода. Если в одной системе запускается много статически связанных приложений, стандартные библиотеки не будут использоваться повторно, поскольку каждое приложение содержит внутри свою собственную копию всего. (Попробуйте du -sh /usr/lib понять масштаб проблемы.)

Попробуйте покопаться в архивах списков рассылки LKML и glibc 10-15 лет назад. Я почти уверен, что давно видел что-то связанное с LKML.

person Dummy00001    schedule 09.08.2010
comment
К сожалению, они не упомянули и другую сторону: статические связанные двоичные файлы занимают на 90% меньше времени на запуск и имеют гораздо меньшие накладные расходы на грязную страницу, чем их аналоги с динамической связью. В наши дни форк eglibc glibc снова сделал статическое связывание по крайней мере наполовину возможным, но если вы действительно хотите использовать статическое связывание без гигантских двоичных файлов и ошибок / проблем, таких как nss, вам, вероятно, потребуется использовать другую реализацию libc. - person R.. GitHub STOP HELPING ICE; 18.11.2010
comment
@R: вы написали, ... но если вы действительно хотите использовать статическое связывание без гигантских двоичных файлов и ошибок / проблем, таких как nss, вам, вероятно, потребуется использовать другую реализацию libc. Кто-нибудь знает реализацию libc, которая обеспечивает статический доступ к nss? Мне нужен статический доступ к getgrgid_r () в среде NIS. Теоретически кто-то может реализовать grgetgid_r и другие подобные подпрограммы, используя статический доступ к базовым подпрограммам NIS. Кто-нибудь на самом деле это сделал? - person ; 11.05.2011
comment
Во всех традиционных библиотеках с поддержкой NIS подпрограммы были статически включены - никакой ерунды NSS. NSS был изобретен намного позже. uClibc не использует модели динамической загрузки, такие как NSS, и я на 99% уверен, что он поддерживает NIS. - person R.. GitHub STOP HELPING ICE; 06.02.2012
comment
Я думаю, что мой ответ устарел: я связал статически приложения среднего размера без каких-либо проблем на Ubuntu 14.04. Но причина того, почему статические ссылки плохи, остается прежней. Если, конечно, кому-то серьезно не нужны бонусы, перечисленные выше R .., и они перевешивают недостатки. - person Dummy00001; 01.01.2016
comment
Динамически подключаемую библиотеку можно переключить на ту же копию с измененным телом функции, содержащим вредоносный код. Никогда не связывайте динамически, если вы не доверяете источнику (никогда не доверяйте источнику, иначе у вас проблемы). Кстати, скрытые суперкомпьютеры давным-давно взломали CRC. - person Ako; 24.07.2019
comment
@R .. статические связанные двоичные файлы занимают на 90% меньше времени на запуск и имеют гораздо меньшие накладные расходы на грязную страницу, чем их аналоги с динамической связью - было бы здорово увидеть контрольную ссылку для этого утверждения. - person yugr; 21.12.2019
comment
@yugr: у меня есть тестовая программа, которая измеряет время, прошедшее непосредственно перед execve до первой строки main после самовыполнения. Для тривиальной программы без разделяемых библиотек, кроме libc, статическая компоновка занимает примерно на 50% меньше времени для самовыполнения, и это время находится в диапазоне десятков или сотен микросекунд в зависимости от скорости машины. Добавьте несколько общих библиотек, и вы легко сможете уменьшить их на 90%. Вы сравниваете время O (n) с временем O (1), поэтому независимо от того, насколько мала стоимость каждой библиотеки, вы можете достичь произвольно близкой к 100%, но на практике это занимает всего несколько. - person R.. GitHub STOP HELPING ICE; 21.12.2019
comment
@R .. Интересно, теперь я вижу, что Prelink сообщил о похожих результатах. Я предполагаю, что накладные расходы в основном связаны с обработкой перемещения среды выполнения GOT / PLT и рекурсивным отслеживанием зависимостей? - person yugr; 21.12.2019
comment
@yugr: Даже mmap накладных расходов достаточно, чтобы сделать их значительными при большом количестве библиотек. Для небольших библиотек mmap время все равно будет преобладать, но для больших (особенно C ++) библиотек время перемещения, включая подкачку по запросу на каждой странице данных / GOT, которую необходимо исправить, является доминирующим фактором. - person R.. GitHub STOP HELPING ICE; 21.12.2019
comment
@R .. Вы думали об этом в блоге? Я уверен, что многим хотелось бы увидеть подробные графики и цифры. - person yugr; 21.12.2019

Я думаю, что это очень раздражает, и я считаю высокомерным называть функцию «бесполезной», потому что у нее есть проблемы с определенными вариантами использования. Самая большая проблема с подходом glibc заключается в том, что он жестко кодирует пути к системным библиотекам (gconv, а также nss), и поэтому он ломается, когда люди пытаются запустить статический двоичный файл в дистрибутиве Linux, отличном от того, для которого он был создан.

В любом случае, вы можете обойти проблему gconv, установив GCONV_PATH так, чтобы он указывал на соответствующее местоположение, это позволило мне взять двоичные файлы, созданные на Ubuntu, и запустить их в Red Hat.

person Ketil    schedule 14.12.2010

Статические ссылки снова на подъеме!

  • Линус Торвальдс поддерживает статические ссылки и выразил озабоченность по поводу количества статических ссылок в дистрибутивах Linux (см. также это обсуждение).
  • Many (most?) Go programming language executables are statically linked.
    • The increased portability and backward compatibility is one reason for them being popular.
  • Other programming languages have similar efforts to make static linking really easy, for example:
    • Haskell (I am working on this effort)
    • Zig (см. здесь для подробностей)
  • Настраиваемые дистрибутивы Linux / наборы пакетов, например NixOS / nixpkgs позволяют статически связывать большую часть своих пакетов (например, его набор пакетов pkgsStatic может предоставлять все виды статически связанных исполняемых файлов) .
  • Статическая компоновка может улучшить удаление неиспользуемого кода во время компоновки, уменьшая размер исполняемых файлов.
  • Такие библиотеки, как musl, делают статическое связывание простым и правильным.
  • С этим согласны некоторые крупные лидеры индустрии программного обеспечения. Например, Google пишет новую библиотеку libc, ориентированную на статическое связывание (поддерживает статическое связывание без PIE и статическое связывание с PIE, мы не собираемся вкладывать средства в [в] поддержку динамической загрузки и связывания).
person nh2    schedule 26.06.2019
comment
Спустя почти 10 лет после того, как был задан первоначальный вопрос, это хорошая новость. Я лично вижу преимущество, поскольку я работаю в регулируемой отрасли, где встроенные цели, которые у меня есть, менее гибки для libc обновлений. Но я всегда могу предоставить новый двоичный файл для моей (полностью) статически связанной программы устройствам в полевых условиях в любое время. - person Subin Sebastian; 16.08.2019
comment
Было бы справедливо упомянуть недостатки статической компоновки (более медленное исправление уязвимостей, раздутые обновления пакетов, увеличенное время компоновки). - person yugr; 20.12.2019
comment
@yugr Увеличение времени ссылки, вероятно, правда. Я не думаю, что остальные верны. Статический и динамический режим не влияет на скорость исправления уязвимостей; это зависит только от того, кто работает над выпуском обновлений. Если их предоставляет дистрибутив, они одинаково быстры, а если их предоставляет сторонний поставщик, они могут быть быстрее или медленнее, чем выбранный вами дистрибутив. Размер обновлений зависит от того, с чем вы сравниваете. Обычный дистрибутив, такой как Ubuntu, может передавать меньше байтов с общими объектами, но часто, например, Образы Docker должны обновляться оптом и превышать размер статических exes. - person nh2; 24.12.2019
comment
Я не думаю, что остальные верны - вероятно, но тот же принцип может быть применен к вашему ответу) Я смотрю с позиции среднего пользователя настольного компьютера Linux (который использует некоторые популярные дистрибутивы и, возможно, несколько приложений от сторонних разработчиков) . - person yugr; 24.12.2019
comment
Статическое и динамическое не влияет на скорость исправления уязвимостей ... если их предоставляет третья сторона, они могут быть быстрее или медленнее - я бы сказал, что сторонний поставщик в основном ориентирован на функциональность и / или производительность ПО, безопасность - это скорее гражданин второго сорта. И в любом случае стороннему провайдеру придется выполнять дублирующую работу дистрибутива по отслеживанию проблем безопасности (что означает, что на его продукт будет потрачено меньше ресурсов). - person yugr; 24.12.2019
comment
Обычному дистрибутиву, например Ubuntu, может потребоваться передать меньше байтов с общими объектами - да, как обычного пользователя меня в основном интересует этот вариант использования. но часто например Образы Docker должны обновляться оптом и быть больше, чем статические exes - образы Docker могут хотя бы кэшироваться (хотя бы частично), тогда как статические исполняемые файлы всегда должны быть полностью повторно загружены при каждом обновлении. - person yugr; 24.12.2019

Статические ссылки, кажется, не пользуются большой популярностью в мире Linux. Вот мое мнение.

Люди, которые не видят привлекательности статического связывания, обычно работают в сфере ядра и операционной системы нижнего уровня. Многие разработчики библиотек * nix потратили всю свою жизнь на решение неизбежных проблем, связанных с попытками связать вместе сотню постоянно меняющихся библиотек, - задача, которую они выполняют каждый день. Взгляните на автоинструменты, если вы когда-нибудь захотите узнать, какие сальто сальто они выполняют.

Но не следует ожидать, что все остальные будут тратить на это большую часть своего времени. Статическая компоновка поможет вам избавиться от оттока библиотеки. Разработчик может обновлять зависимости своего программного обеспечения в соответствии с расписанием программного обеспечения, а не вынужден делать это при появлении новых версий библиотеки. Это важно для пользовательских приложений со сложными пользовательскими интерфейсами, которым необходимо управлять потоком множества низкоуровневых библиотек, от которых они неизбежно зависят. И поэтому я всегда буду поклонником статических ссылок. Если вы можете статически связать кросс-скомпилированный переносимый код C и C ++, вы в значительной степени сделали мир своей устрицей, поскольку вы можете быстрее доставлять сложное программное обеспечение на широкий спектр постоянно растущих в мире устройств.

Есть с чем не согласиться с других точек зрения, и приятно, что программное обеспечение с открытым исходным кодом позволяет все это.

person moodboom    schedule 06.07.2016
comment
Было бы справедливо упомянуть о недостатках статической компоновки: невосприимчивость к обновлениям библиотеки (и, следовательно, исправлениям ошибок / уязвимостей), более длительное время компоновки и большие размеры исполняемых файлов. - person yugr; 20.12.2019
comment
Au contrere, вы по-прежнему делаете обновления библиотеки, когда вам нужно, например, когда вы приближаетесь к выпуску, и стоит включить последние исправления безопасности - это меньше потраченного времени. Попробуйте ниндзя, чтобы ускорить время ссылки. Это довольно редкая ситуация, когда размер двоичного файла имеет большое значение - возможно, в крошечных встроенных пространствах, но в этом случае вы можете лишить свою ОС общих библиотек. Опять же, варианты использования различаются, ymmv, все такое. - person moodboom; 21.12.2019
comment
вы по-прежнему делаете обновления библиотеки, когда вам нужно - обычно человек, который действительно нуждается в обновлении, - это пользователь вашего приложения, который теперь не может не просто полагаться на автоматические обновления безопасности, предоставляемые разработчиками дистрибутива, но должен отслеживать в зависимости от того, какие версии библиотеки используются в вашем статически связанном двоичном файле (или положитесь на вас, чтобы своевременно повторно связать указанный двоичный файл с фиксированными библиотеками, дублируя работу группы безопасности дистрибутива). - person yugr; 21.12.2019
comment
Попробуйте ниндзя, чтобы ускорить время компоновки - я не уверен, как ниндзя может ускорить мой компоновщик. - person yugr; 21.12.2019
comment
Это довольно редкая ситуация, когда размер двоичного файла имеет большое значение - ни разу новый основной язык не связывает все свои исполняемые файлы, текущие и будущие, статически, что ухудшает ситуацию с каждым новым пакетом. - person yugr; 21.12.2019
comment
Бурный рост док-контейнеров демонстрирует большой интерес к многократному захвату всей статической среды за счет размера диска. Но опять же, как я уже сказал, это зависит от обстоятельств, вы можете иметь дело с крошечным исполняемым файлом, который вам нужно загрузить в среду busybox или еще что-то. На данный момент мы спорим в Интернете. Я признаю, что бывают случаи, когда упомянутые вами моменты действительны. - person moodboom; 22.12.2019

Тот факт, что вам нужно динамически связываться со службой NSS, не означает, что вы не можете статически связываться с какой-либо другой библиотекой. Все, что говорится в FAQ, это то, что даже «статически» связанные программы имеют некоторые динамически подключаемые библиотеки. Это не говорит о том, что статическое связывание «невозможно» или что оно «не работает».

person Dean Harding    schedule 07.08.2010
comment
Это означает, что это не полностью статичная сборка. Фактически, в большинстве случаев для правильной работы требуется установка той же версии glibc. А зачем мне такая статическая сборка? - person Shcheklein; 07.08.2010
comment
@Dead: исполняемые файлы статической сборки не имеют динамического компоновщика, поэтому не могут загружать разделяемые библиотеки. Лучшая справочная информация, которую я смог найти: en.wikipedia.org/wiki/Static_build. Как я уже писал ниже, Linux не поддерживает это намеренно. - person Dummy00001; 09.08.2010
comment
Поздно к игре, но при работе с очень жесткими системами, где, скажем, компилятор C ++ в одной системе поддерживает только C ++ 98, а код, написанный на C ++ 11, переносится ... компилируем его в системе RHEL 6, которая поддерживает C ++ 0x, а затем копирование двоичного файла в более старую систему RHEL 5, которая не поддерживает C ++ 0x ... если бы я мог статически связать все приложение, то оно работало бы в системе RHEL 5. Пример того, почему статические ссылки полезны. Но я не могу - потому что, например, в g ++ 4.4.7 нет параметров компилятора G ++ для статической компоновки в библиотеках C ++. - person Minok; 18.12.2015

Добавление других ответов:

По причинам, указанным в других ответах, это не рекомендуется для большинства дистрибутивов Linux, но на самом деле есть дистрибутивы, которые созданы специально для запуска статически связанных двоичных файлов:

Из описания стали:

static linux основан на вручную подобранной коллекции лучших инструментов для каждой задачи, и каждый инструмент статически связан (включая некоторые X-клиенты, такие как st, surf, dwm, dmenu),

Он также нацелен на уменьшение размера двоичного файла за счет избегания glibc и других раздутых библиотек GNU, где это возможно (ранние эксперименты показывают, что статически подключаемые двоичные файлы обычно меньше, чем их динамически подключаемые аналоги glibc !!!). Обратите внимание: это в значительной степени противоречит тому, что Ульрих Дреппер считает статическим связыванием.

Благодаря дополнительному преимуществу, заключающемуся в том, что статически связанные двоичные файлы запускаются быстрее, распределение также нацелено на повышение производительности.

Статическое связывание также помогает уменьшить зависимость.

Вы можете узнать больше об этом в этом вопросе о статическом и динамическом связывании.

person Farid Nouri Neshat    schedule 01.01.2015