Шаг за шагом C результат компиляции в segfault - PullRequest
4 голосов
/ 03 марта 2020

Я пытаюсь понять C компиляцию

Учитывая этот простой C код в main. c:

int main() {
    int a;
    a = 42;
    return 0;
}

Я выполнил следующие операции:

cpp main.c main.i
/usr/lib/gcc/x86_64-linux-gnu/9/cc1 main.i -o main.s
as -o main.o main.s
ld -o main.exe main.o

При выполнении main.exe у меня возникает ошибка сегментации.

Как получить хорошую адресацию памяти в этом примере?

1 Ответ

7 голосов
/ 03 марта 2020

Когда я пытаюсь выполнить последовательность команд из вашего вопроса в системе Ubuntu 19.10 x86_64, я получаю предупреждение от ld:

ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000

Это признак того, что что-то не так.

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

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

Запустите, например,

gcc -v -o main.exe main.o

, чтобы увидеть, какие другие файлы добавляются в вашу программу. В моей системе это показывает несколько файлов с именами, начинающимися с crt, что означает "C runtime".

Если вы не используете gcc для связи своей программы, но используете ld напрямую, Вы должны вручную добавить все необходимые объектные файлы аналогично тому, как компилятор сделал бы это автоматически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...