Как отладить экспериментальный набор инструментов для создания искаженных исполняемых файлов
Я работаю над кросс-компиляцией экспериментального набора инструментов 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
в качестве статического исполняемого файла и использовал -v
gcc
/ 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
для скомпилированного двоичного файла и некоторых других двоичных файлов вашего хоста, чтобы увидеть возможные различия.