От чего зависит моя программа, скомпилированная с помощью gcc?

Я пытаюсь понять зависимости программы на C и постепенно понимаю, что gcc main.c -o main скрывает множество деталей.

Вот мой эксперимент (ubuntu-wsl-x64):

Как видите, моя программа связана с

  • GNU libc (по символической ссылке libc.so.6)
  • Компоновщик GNU (ld-linux-x86-64.so.2)
  • Странная динамическая библиотека (linux-vdso.so.1)

Насколько я понимаю, linux-vdso.so.1 будет реализовывать определенный API libc для повышения скорости определенных системных вызовов.

Вопросы:

  1. Почему linux-vdso.so.1 еще не включен в libc?
  2. Почему ld динамически связан с моим исполняемым файлом? Используется ли он во время выполнения?
  3. Насколько я понимаю, моя программа также должна зависеть от libgcc и crt0, связаны ли они статически?
  4. Должен быть скрыт -I, чтобы программа могла видеть заголовочный файл libc. Я прав? Я так, где они?
  5. Я упускаю что-то еще?

Спасибо, добрые незнакомцы.

Пожалуйста, публикуйте код, данные и результаты в виде текста, а не скриншотов (как форматировать код в сообщениях ). Почему мне не следует загружать изображения кода/данных/ошибок? idownvotedbecau.se/imageofcode

Barmar 06.08.2024 23:36

«Он используется во время выполнения?» Я думаю, что это часть механизма динамического связывания.

Barmar 06.08.2024 23:37

Привет, Бармар, я буду иметь это в виду. Тем не менее, в этом случае маркированный список суммирует изображение.

gberth 06.08.2024 23:37

«Я думаю, что это часть механизма динамического связывания». Конечно, но если это часть этапов набора инструментов, зачем связывать его с исполняемым файлом?

gberth 06.08.2024 23:38

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

Streve Ford 06.08.2024 23:40

Это ld загрузчик исполняемого файла, а не компоновщик.

Stas Simonov 06.08.2024 23:43

Конечно, но если это часть этапов набора инструментов, зачем связывать его с исполняемым файлом? - динамическое связывание происходит во время выполнения. Отсюда «динамический».

Eugene Sh. 06.08.2024 23:43

@StasSimonov Не точно: linux.die.net/man/8/ld-linux

Eugene Sh. 06.08.2024 23:47

@EugeneSh Я хочу избежать путаницы.

Stas Simonov 06.08.2024 23:53

Ответ на ваш вопрос №5: «Да, стоит несколько книг». Начните с компоновщиков и загрузчиков (Джон Левин) и стандартной библиотеки C (П.Дж. Плаугер). Обе книги немного устаревшие, но по сути правильны и хорошо написаны.

zwol 07.08.2024 01:30

Добавьте опцию -v при компиляции. Он сообщит, какие команды выполняются и их аргументы. За кулисами происходит много всего.

Jonathan Leffler 07.08.2024 02:19

Пожалуйста, отредактируйте свой вопрос, чтобы задать одну вещь; вопросы о переполнении стека должны задавать один вопрос, а не несколько.

TylerH 07.08.2024 17:24

@zwol ""да - стоит несколько книг" хе-хе, ты абсолютно прав! Когда-нибудь я туда доберусь. Спасибо за рекомендацию.

gberth 07.08.2024 20:13

@TylerH Это один вопрос: что скрывает gcc? Я разложил свой вопрос на подвопросы, чтобы помочь аудитории понять, что я имею в виду. Если это имеет смысл.

gberth 07.08.2024 20:15

@JonathanLeffler хорошая идея. Спасибо !

gberth 07.08.2024 20:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
15
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как видите, моя программа связана с

  • GNU libc (через символическую ссылку libc.so.6)

Да.

  • Компоновщик GNU (ld-linux-x86-64.so.2)

Нет. Это не компоновщик GNU (ld). Это динамический компоновщик Linux. Он служит стандартным загрузчиком программ ELF в Linux. Для запуска каждого исполняемого файла ELF необходим такой загрузчик.

  • Странная динамическая библиотека (linux-vdso.so.1)

Вроде, как бы, что-то вроде. «vdso» — это инициализм «виртуального динамического общего объекта». Именно этот параметр предоставляется каждому процессу ядром Linux, и стандартная библиотека C использует его для различных служб ядра. Он не входит в состав libc, поскольку по сути является частью ядра.

  1. Насколько я понимаю, моя программа также должна зависеть от libgcc и crt0, они связаны статически?

Некоторые программы, скомпилированные с помощью GCC, зависят от libgcc. Другие этого не делают. Это зависит от программы. libgcc может быть скомпонован статически - в GCC для этого есть опция командной строки - но если вы не просили об этом, то, вероятно, это не так.

Я не знаю, что такое crt0, может быть это: https://en.wikipedia.org/wiki/Crt0? Насколько мне известно, это не представляет собой отдельную общую библиотеку, поэтому ldd не буду вам об этом рассказывать.

Должен быть скрыт -I, чтобы программа могла видеть заголовочный файл libc. Я прав? Я так, где они?

Нет, вы не правы. GCC имеет путь поиска по умолчанию для включаемых файлов, который включает заголовки стандартной библиотеки, с которой он интегрирован. Вы используете опцию -I для добавления каталогов в этот путь поиска, но она вам не нужна для заголовков стандартной библиотеки или для других, установленных по этому пути (и как было бы больно, если бы вы это сделали!). Если вы спросите, Gcc сообщит вам, какой путь поиска используется по умолчанию.

  1. Я упускаю что-то еще?

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

Вы можете использовать параметр -v для gcc, чтобы увидеть путь поиска (по умолчанию) для включаемых файлов («скрытые» параметры -I), а также многое другое.

Chris Dodd 07.08.2024 07:26

Это очень полезно. Я понимаю, что мой вопрос открыт. По моему опыту, такие знания трудно приобрести. Так что большое спасибо, что нашли время.

gberth 07.08.2024 20:04

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