如何调试生成格式错误的可执行文件的实验工具链

我正在使用
clang(而不是gcc),
compiler-rt(而不是libgcc),libunwind(可在
http://llvm.org/git/libunwind.git获得)(而不是libgcc_s),
lld(而不是GNU ld),
libcxx(而不是使用libgcc)交叉编译实验性GNU免费Linux工具链. libstdc),
libcxxabi(而不是不确定,我不清楚libstdc和它的ABI之间的GNU区别)和
musl(而不是glibc).

使用musl based gcc cross compiler和一些补丁我已成功编译了上述所有内容并成功编译并链接了一个简单的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运行时启动的某个地方.我甚至无法使用布局asm和stepi逐步完成程序集,所以我真的不知道如何找出错误发生的位置(调试我的工具链).

我已经通过使用GNU binutils ld使用交叉编译的库和目标文件成功链接hello world对象(静态)来确认问题存在于lld,这导致了一个函数式hello world程序.然而,由于lld成功链接,我无法确定故障发生的位置.

注意我将hello编译为静态可执行文件,并使用-v gcc / clang选项验证所有正确的库和目标文件是否已链接.

注意online GDB documentation有关于上述错误的以下内容:

On Unix systems, by default, if a shell is available on your target, gdb) uses it to start your program. Arguments of the run command are passed to the shell, which does variable substitution, expands wildcard characters and performs redirection of I/O. In some circumstances, it may be useful to disable such use of a shell, for example, when debugging the shell itself or diagnosing startup failures such as:

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

which indicates the shell or the wrapper specified with ‘exec-wrapper’ crashed, not your program.

我不认为这是真的,考虑到我正在使用什么,并且当我使用GNU ld时问题不会发生,并且因为建议的解决方案(设置startup-with-shell off)不起作用.

最佳答案 交叉编译意味着编译在主机上完成,编译的输出是二进制文件,它应在目标机器上运行.因此,编译的二进制文件与主机CPU不兼容.相反,如果您的目标支持此功能,您可以在那里运行二进制文件,并使用工具链中的调试器远程连接到运行的二进制文件(如果支持).或者,调试器也可以在目标处可用,您可以在位置调试二进制文件.

只是为了获得更多的感觉,尝试使用命令文件来编译二进制文件,以及主机的其他一些二进制文件,以查看可能的差异.

点赞