ошибка seg при запуске скомпилированного кода arm-elf-gcc

#macos #embedded #arm #elf

#macos #встроенный #arm #elf

Вопрос:

Используя MacPorts, я только что установил arm-elf-gcc на свой MacBook Pro. Это сработало безупречно, и, похоже, все работает нормально.

Однако после компиляции простой тестовой программы hello world на C и C и попытки запуска на целевой плате (плате на базе ARM9 под управлением Debian Linux) они немедленно обнаруживают ошибку seg.

Я немного запутался в том, как приступить к отладке этого, поскольку на целевой плате доступно ограниченное количество инструментов и нет gdb. Я успешно собрал и запустил другой код, используя кросс-компилятор, размещенный на Linux, поэтому он должен работать.

Есть идеи?

Следуя предложению, которое я создал и запустил gdbserver, я получаю следующее в gdb на хосте:

Программа получила сигнал SIGSEGV, ошибка сегментации. 0x00000000 в ?? ()

Я подумал, что это может быть проблема со стандартными библиотеками c, поэтому я удалил все вызовы и получил только пустой main, который возвращает 0, он скомпилирован с помощью -Wall -g hello-arm.cpp -статический. В качестве теста я скомпилировал тот же исходный код с помощью кросс-компилятора, размещенного на Linux, и он запускается и завершается нормально. Единственное различие, которое я вижу, заключается в том, что скомпилированная версия Linux более чем в два раза больше и разница в выводе из команды file:

arm-elf-gcc: 32-разрядный исполняемый файл ELF LSB, ARM, версия 1, статически связанный, не удален

arm-*-linux: 32-разрядный исполняемый файл ELF LSB, ARM, версия 1, статически связанный, для GNU/ Linux 2.4.18, не удален

Ответ №1:

Обычным методом отладки в этой ситуации является запуск gdbserver на целевой плате и подключение к нему (через Ethernet) с помощью gdb, запущенной на главном компьютере.

С другой стороны, вы могли бы попробовать сравнить сборку в программе «Hello World», скомпилированной на Mac, и в (рабочей) программе, скомпилированной на Linux, чтобы увидеть, в чем разница.

Ответ №2:

Покопавшись пару дней, я начинаю немного больше понимать о встроенных компиляторах. Я не был действительно уверен в разнице между arm-elf-gcc, установленным через MacPorts, и набором инструментов arm-unknown-linux, который я установил в своем Linux box. Я только что наткнулся на PDF-файл под названием «Введение в компилятор GNU«, который содержит следующий абзац:

Важно: Использование компилятора GNU для создания вашего исполняемого файла не совсем то же самое, что самостоятельное использование компоновщика GNU arm-elf-ld. Причина в том, что компилятор GNU автоматически связывает ряд стандартных системных библиотек с вашим исполняемым файлом. Эти библиотеки позволяют вашей программе взаимодействовать с операционной системой, использовать стандартные функции библиотеки C, использовать определенные функции языка и операции (такие как разделение) и так далее. Если вы хотите точно увидеть, какие библиотеки подключаются к исполняемому файлу, вы должны передать компилятору подробный флаг -v.

Это имеет важные последствия для встроенных систем! Такие системы обычно не имеют операционной системы. Это означает, что компоновка в системных библиотеках почти всегда бессмысленна: например, если нет операционной системы, то вызов стандартной функции printf не имеет особого смысла.

Поэтому, когда я вернусь к своей машине разработчика позже, я определю библиотеки, связанные со сборкой Linux, и добавлю их в сборку arm-elf-gcc.

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

Комментарии:

1. Сейчас я сталкиваюсь с той же проблемой. Вы когда-нибудь получали ответ?

2. Я действительно не разобрался в сути этого, и я думаю, что это больше связано с моим непониманием проблемы. Однако я получил работающий кросс-компилятор ARM, установив Crosspack ARM из obdev.at/products/crosspack/index.html .