我正在使用clang
(而不是gcc
)、compiler-rt
(而不是libgcc
)、libunwind
(可在http://llvm.org/git/libunwind.git上获得)(而不是libgcc_s
)、lld
(而不是 GNU ld
)交叉编译一个实验性的 GNU 自由 Linux 工具链,libcxx
(而不是libstdc++
),libcxxabi
(而不是不确定,我不清楚 GNUlibstdc++
及其 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
and逐步完成程序集stepi
,所以我真的不知道如何找出错误发生的确切位置(调试我的工具链)。
我已经确认问题在于lld
使用 GNU binutilsld
使用交叉编译的库和目标文件成功链接 hello world 对象(静态),从而产生一个功能性的 hello world 程序。但是,由于lld
成功链接,我无法确定发生故障的位置。
注意我编译hello
为静态可执行文件并使用-v
gcc
/clang
选项来验证所有正确的库和目标文件是否已链接它。
注意在线 GDB 文档对上述错误有以下说法:
在 Unix 系统上,默认情况下,如果您的目标上有可用的 shell,gdb) 使用它来启动您的程序。run 命令的参数被传递给 shell,shell 执行变量替换、扩展通配符和执行 I/O 重定向。在某些情况下,禁用 shell 的这种使用可能很有用,例如,在调试 shell 本身或诊断启动失败时,例如:
(gdb) run
Starting program: ./a.out
During startup program terminated with signal SIGSEGV, Segmentation fault.
这表明用 'exec-wrapper' 指定的外壳或包装器崩溃了,而不是你的程序。
我认为这不是真的,考虑到我正在使用的东西,并且当我使用 GNU 时问题不会发生ld
,并且因为建议的解决方案 ( set startup-with-shell off
) 不起作用。