Подтвердить что ты не робот

Самая короткая программа на C, по-прежнему вызывает segfault

На какое-то мгновение я очень гордился тем, что написал свою первую программу C без ошибок. Вот весь исходный код:

int main;

Он компилируется даже без int, но выдается предупреждение (даже без -Wall) и, как программист, который нацелен на программу без ошибок, я рассматриваю их как ошибки.

С удовольствием скомпилировав это приложение, я сразу же бросился его запускать. К моему удивлению, появилась ошибка ошибки сегментации...


Теперь серьезно. Что именно происходит?

Моя догадка заключается в следующем: это отсутствие определения main. Это так очевидно, но компилятор разрешает это. OK, main может быть задано в другом блоке. Но даже компоновщик ничего не делает по этому поводу. Любая конкретная причина, по которой?

4b9b3361

Ответ 1

Слово main является юридическим именем для любой переменной. Типичным вариантом использования является предоставление функции имени main компилятору, который компилирует его в файл объекта, который, в свою очередь, связан с crt0.o, который обеспечивает инициализацию для времени выполнения (распределение стека и т.д.), и перескакивает на метку main.

В объектных файлах C символы не связаны с прототипами, и компоновщику удается привязать глобальную переменную int main; к главной программе, к которой нужно подпрыгнуть. Однако эта программа является мусором. Скорее всего, он инициализируется как нули, но вскоре процессор встречает либо случайную инструкцию, которая обращается к памяти за пределами распределенного пространства программ (стек + куча), либо поток команд достигает пределов зарезервированного кодового пространства.

Оба будут вызывать ошибку сегментации. И на самом деле, если система работает с архитектурой с флагами eXecution, программа segfaults с первой попытки перейти на сегмент данных или страницу без разрешения на выполнение.

Дальнейшее чтение для поддержки обсуждения в комментариях: Предотвращение выполнения данных, NX_bit