Как отладить экспериментальный набор инструментов для создания искаженных исполняемых файлов

Я работаю над кросс-компиляцией экспериментального набора инструментов Linux для GNU, используя clang (вместо gcc), compiler-rt (вместо libgcc), libunwind (доступно по адресу http://llvm.org/git/libunwind.git) (вместо libgcc_s), lld (вместо GNU ld), libcxx (вместо libstdc++), libcxxabi (вместо того, чтобы не быть уверенным, мне неясно различие GNU между libstdc++ и его ABI) и musl (вместо glibc).

Используя musl основан gcc кросс-компилятор и несколько патчей, мне удалось успешно скомпилировать все вышеперечисленное и успешно скомпилировать и связать с ним простую программу hello world C. Однако, похоже, что-то пошло не так, поскольку запуск программы hello world приводит к ошибке сегментации:

$ ./hello
Segmentation fault
$ 

Обычно я просто отлаживаю его с помощью gdb, но в этом и заключается проблема:

$ gdb ./hello
Reading symbols from ./hello...Dwarf Error: Could not find abbrev number 5 in CU at offset 0x52 [in module /home/main/code/main/asm/hello]
(no debugging symbols found)...done.
(gdb) start
Temporary breakpoint 1 at 0x206
Starting program: /hello 
During startup program terminated with signal SIGSEGV, Segmentation fault.
(gdb) 

Кажется, я никак не могу пройтись по программе, я полагаю, потому что ошибка происходит где-то при раннем запуске C. Я не могу даже пройти через сборку, используя layout asm а также stepi так что я действительно не знаю, как узнать, где именно происходит ошибка (для отладки моей цепочки инструментов).

Я подтвердил, что проблема связана с lld с помощью GNU binutils ld успешно связать объект hello world (статически) с помощью кросс-скомпилированных библиотек и объектных файлов, что приводит к созданию функциональной программы hello world. поскольку lld успешно ссылки, однако я не могу точно определить, где происходит сбой.

Обратите внимание, я скомпилировал hello в качестве статического исполняемого файла и использовал -vgcc / clang возможность проверить, что все правильные библиотеки и объектные файлы были связаны с ним.

Обратите внимание, что онлайн-документация по GDB содержит следующую информацию об указанной ошибке:

В системах Unix по умолчанию, если на вашей цели доступна оболочка, gdb) использует ее для запуска вашей программы. Аргументы команды run передаются в оболочку, которая выполняет подстановку переменных, расширяет символы подстановки и выполняет перенаправление ввода-вывода. В некоторых случаях может быть полезно отключить такое использование оболочки, например, при отладке самой оболочки или диагностике ошибок при запуске, таких как:

(gdb) run
Starting program: ./a.out
During startup program terminated with signal SIGSEGV, Segmentation fault.

что указывает на сбой оболочки или оболочки, указанной с помощью exec-wrapper, а не вашей программы.

Я не думаю, что это правда, учитывая то, с чем я работаю и что проблема не возникает, когда я использую GNU ld и потому что предложенное решение (set startup-with-shell off) не работает.

1 ответ

Решение

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

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

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