如何调试生成格式错误的可执行文件的实验性工具链
How to debug an experimental toolchain producing malformed executables
我正在使用 clang
(instead of gcc
), compiler-rt
(instead of libgcc
), libunwind
(available at http://llvm.org/git/libunwind.git) (instead of libgcc_s
), lld
(instead of GNU ld
), libcxx
(instead of libstdc++
), libcxxabi
(instead of not sure, I'm unclear on the GNU distinction between libstdc++
and its ABI) and musl
(而不是 glibc
)交叉编译实验性 GNU 免费 Linux 工具链。
使用 musl
based gcc
cross compiler 和一些补丁,我成功地编译了上述所有内容,并成功编译 link 一个简单的 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
使用交叉编译的库和目标文件成功地 link hello world 对象(静态) ,这将生成一个功能性的 hello world 程序。由于 lld
成功 links,但是,我无法查明故障发生的位置。
注意我将 hello
编译为静态可执行文件并使用 -v
gcc
/clang
选项来验证所有正确的库和目标文件是 link编辑它。
注意 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 意味着编译是在 host 机器上完成的,编译的输出是应该 运行 在 机器上的二进制文件]目标 机器。因此,编译后的二进制文件与您的 host CPU 不兼容。相反,如果你的 target 支持这个,你可以 运行 那里的二进制文件,并使用工具链中的调试器远程连接到 运行ning 二进制文件(如果支持)。或者,调试器也可以在 目标 上使用,您可以调试已经存在的二进制文件。
为了获得更多感受,请尝试对编译后的二进制文件和您主机的其他一些二进制文件使用命令 file
,以查看可能存在的差异。
我正在使用 clang
(instead of gcc
), compiler-rt
(instead of libgcc
), libunwind
(available at http://llvm.org/git/libunwind.git) (instead of libgcc_s
), lld
(instead of GNU ld
), libcxx
(instead of libstdc++
), libcxxabi
(instead of not sure, I'm unclear on the GNU distinction between libstdc++
and its ABI) and musl
(而不是 glibc
)交叉编译实验性 GNU 免费 Linux 工具链。
使用 musl
based gcc
cross compiler 和一些补丁,我成功地编译了上述所有内容,并成功编译 link 一个简单的 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
使用交叉编译的库和目标文件成功地 link hello world 对象(静态) ,这将生成一个功能性的 hello world 程序。由于 lld
成功 links,但是,我无法查明故障发生的位置。
注意我将 hello
编译为静态可执行文件并使用 -v
gcc
/clang
选项来验证所有正确的库和目标文件是 link编辑它。
注意 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 意味着编译是在 host 机器上完成的,编译的输出是应该 运行 在 机器上的二进制文件]目标 机器。因此,编译后的二进制文件与您的 host CPU 不兼容。相反,如果你的 target 支持这个,你可以 运行 那里的二进制文件,并使用工具链中的调试器远程连接到 运行ning 二进制文件(如果支持)。或者,调试器也可以在 目标 上使用,您可以调试已经存在的二进制文件。
为了获得更多感受,请尝试对编译后的二进制文件和您主机的其他一些二进制文件使用命令 file
,以查看可能存在的差异。