我正在使用clang
(而非gcc
),compiler-rt
(而非libgcc
),{{1}进行交叉编译实验性GNU免费Linux工具链(可在http://llvm.org/git/libunwind.git)(而不是libunwind
),lld
(而不是GNU libgcc_s
),libcxx
(而不是ld
) ,libcxxabi
(而不是不确定,我不清楚libstdc++
与其ABI之间的GNU区别)和musl
(而不是libstdc++
)。
使用musl
based gcc
cross compiler和一些补丁,我成功地编译了上述所有内容并成功编译并链接了一个简单的hello world C程序。然而,似乎出现了一些问题,因为运行hello world程序会导致分段错误:
glibc
通常我只是用gdb调试它,但这就是问题所在:
$ ./hello
Segmentation fault
$
我似乎无法以任何方式单步执行该程序,我猜测是因为错误发生在早期C运行时启动的某个地方。我甚至无法使用$ 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)
和layout asm
逐步完成程序集,所以我真的不知道如何确定错误发生的位置(调试我的工具链)。
我已经确认问题存在于stepi
,使用GNU binutils lld
使用交叉编译的库和目标文件成功链接hello world对象(静态),从而实现功能你好世界节目。但是,由于ld
成功链接,我无法确定故障发生的位置。
注意我将lld
编译为静态可执行文件,并使用hello
-v
/ gcc
选项验证所有正确的库和目标文件是否已链接。< / p>
注意online GDB documentation有关于上述错误的以下内容:
在Unix系统上,默认情况下,如果目标上有shell,gdb)会使用它来启动程序。 run命令的参数传递给shell,它执行变量替换,扩展通配符并执行I / O重定向。在某些情况下,禁用shell的使用可能很有用,例如,在调试shell本身或诊断启动失败时,例如:
clang
表示用'exec-wrapper'指定的shell或包装器崩溃,而不是你的程序。
我不认为这是真的,考虑到我正在使用的内容,并且当我使用GNU (gdb) run
Starting program: ./a.out
During startup program terminated with signal SIGSEGV, Segmentation fault.
时问题不会发生,并且因为建议的解决方案({ {1}})不起作用。
答案 0 :(得分:2)
交叉编译意味着编译是在主机机器上完成的,编译的输出是二进制文件,它应在目标机器上运行。因此,编译的二进制文件与主机 CPU不兼容。相反,如果您的目标支持此功能,您可以在那里运行二进制文件,并使用工具链中的调试器远程连接到正在运行的二进制文件(如果支持)。或者,调试器也可以在目标处使用,您可以在位置调试二进制文件。
为了获得更多感觉,请尝试使用命令file
作为已编译的二进制文件,以及主机的其他一些二进制文件,以查看可能存在的差异。