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

标签 c linux gcc clang lld

我正在使用 clang 交叉编译实验性 GNU 免费 Linux 工具链(而不是 gcc),compiler-rt (而不是 libgcc),libunwind(在 http://llvm.org/git/libunwind.git 可用)(而不是 libgcc_s),lld (而不是 GNU ld),libcxx (而不是 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 运行时启动的某个地方。我什至无法使用 layout asmstepi 逐步执行程序集,所以我真的不知道如何找出错误发生的确切位置(调试我的工具链)。

我已通过使用 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 时问题不会发生,并且因为建议的解决方案 (set startup-with-shell off) 不起作用。

最佳答案

croscompilling 意味着编译是在主机 机器上完成的,编译的输出是应该在目标 机器上运行的二进制文件。因此,编译后的二进制文件与您的主机 CPU 不兼容。相反,如果您的目标 支持此功能,您可以在那里运行二进制文件,并使用工具链中的调试器远程连接到正在运行的二进制文件(如果支持)。或者,调试器也可以在 目标 上使用,您可以调试已经存在的二进制文件。

只是为了获得更多感受,尝试对编译后的二进制文件和主机的其他一些二进制文件使用命令 file 以查看可能的差异。

关于c - 如何调试生成格式错误的可执行文件的实验性工具链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33710113/

相关文章:

node.js - Nodemon 在 Linux 上安装警告

linux - 关于iptables中 "-set-xmark"的一些问题

c - gcc 提示 : variable-sized object may not be initialized

c - 双指针转换,传递给带有 `const void **ptr` 参数的函数

cpu - 自动换档

c - 以邻接矩阵作为参数的 Prim MST

linux - 如何在 Virtualbox 中的 guest 操作系统中下降到命令行

c - 为什么我会收到此错误和警告?错误和警告在描述中

c - C中 volatile 结构中的指针

c - 标准 gcc 发行版中是否有环形缓冲区实现?