带有调试选项的 gcc 编译阶段
Posted
技术标签:
【中文标题】带有调试选项的 gcc 编译阶段【英文标题】:gcc compile stages with debug options 【发布时间】:2017-11-06 19:58:20 【问题描述】:我正在尝试研究与 GCC 不同的编译阶段。
手动分阶段编译
$ g++ -E main.cpp -o main.i # I1
$ g++ -S main.i -o main.s # S1
$ g++ -S main.i -o main.debug.s -ggdb -g3 # S2
$ as main.s -o main.as.o # O1
$ as main.debug.s -o main.as.debug.o # O2
然后完全用“g++ only”再次编译
$ g++ -c main.cpp -o main.gcc.o # G1
$ g++ -c main.cpp -o main.gcc.debug.o -ggdb -g3 # G2
最后
main.as.o 与 main.gcc.o 相同,但没有调试信息
但是
main.as.debug.o 与 main.gcc.debug.o
非常不同为什么?我有什么想念的吗?
这里是工具版本
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++-7
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/7.2.0/libexec/gcc/x86_64-apple-darwin13.4.0/7.2.0/lto-wrapper
Target: x86_64-apple-darwin13.4.0
Configured with: ../configure --build=x86_64-apple-darwin13.4.0 --prefix=/usr/local/Cellar/gcc/7.2.0 --libdir=/usr/local/Cellar/gcc/7.2.0/lib/gcc/7 --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-7 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --enable-checking=release --with-pkgversion='Homebrew GCC 7.2.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-nls
Thread model: posix
gcc version 7.2.0 (Homebrew GCC 7.2.0)
$ as -v
Apple Inc version cctools-862, GNU assembler version 1.38
更新
这里使用 -v 和 -save-temps 选项显示等效命令
#####
# $ g++ -E main.cpp -o main.i # I1
$ cc1plus -E -quiet -v -D__DYNAMIC__ main.cpp -o main.i -fPIC -mmacosx-version-min=10.9.4 -mtune=core2
#####
# $ g++ -S main.i -o main.s # S1
$ cc1plus -fpreprocessed main.i -fPIC -quiet -dumpbase main.i -mmacosx-version-min=10.9.4 -mtune=core2 -auxbase-strip main.s -version -fdump-tree-all-graph -o main.s
#####
# $ g++ -S main.i -o main.debug.s -ggdb -g3 # S2
$ cc1plus -fpreprocessed main.i -fPIC -quiet -dumpbase maini -mmacosx-version-min=10.9.4 -mtune=core2 -auxbase-strip main.debug.s -ggdb -g3 -version -o main.debug.s
#####
$ as main.s -o main.as.o # O1
$ as main.debug.s -o main.as.debug.o # O2
#####
# g++ -c main.cpp -o main.gcc.o # G1
$ cc1plus -E -quiet -v -D__DYNAMIC__ main.cpp -fPIC -mmacosx-version-min=10.9.4 -mtune=core2 -fpch-preprocess -o main.ii
$ cc1plus -fpreprocessed main.ii -fPIC -quiet -dumpbase main.cpp -mmacosx-version-min=10.9.4 -mtune=core2 -auxbase-strip main.gcc.o -version -o main.s
$ as -arch x86_64 -v -force_cpusubtype_ALL -o main.gcc.o main.s
#####
# g++ -c main.cpp -o main.gcc.debug.o -ggdb -g3 # G2
$ cc1plus -E -quiet -v -dD -D__DYNAMIC__ main.cpp -fPIC -mmacosx-version-min=10.9.4 -mtune=core2 -ggdb -g3 -fworking-directory -fpch-preprocess -o main.ii
$ cc1plus -fpreprocessed main.ii -fPIC -quiet -dumpbase main.cpp -mmacosx-version-min=10.9.4 -mtune=core2 -auxbase-strip main.gcc.debug.o -ggdb -g3 -version -o main.s
$ as -arch x86_64 -v -force_cpusubtype_ALL -o main.gcc.debug.o main.s
#####
【问题讨论】:
除了常规选项外,您还可以使用-v
代替gcc
,以查看它如何为您调用工具。
我可以发现的一个区别是您的手动步骤使用 /usr/bin/as 而“g++ only”步骤将使用 gcc 的内置汇编程序(您可以告诉它不要使用正确的命令行选项)。
所以尝试使用g++ -v -Wall -g main.cpp -o mainprog
进行编译
@JesperJuhl gcc 没有“内置汇编程序”,您对 clang 感到困惑。
在您上次更新中,如果您手动运行g++ -g -v main.cpp
打印出的命令,您是否得到与让编译器前端调用所有工具相匹配的.o
?另外,main.debug.s
是否与保存临时文件 .s
相同?
【参考方案1】:
哎呀,这对我来说是微不足道的失败。
原帖
$ g++ -E main.cpp -o main.i # I1
$ g++ -S main.i -o main.s # S1
$ g++ -S main.i -o main.debug.s -ggdb -g3 # S2
我还需要使用调试选项调用 -E 并进入下一阶段....
应该改为...
$ g++ -E main.cpp -o main.debug.i -ggdb -g3 # I2
$ g++ -S main.debug.i -o main.debug.s -ggdb -g3 # S2'
那么以下阶段将生成相同的机器码...
【讨论】:
您在main.cpp
中做了哪些与-g
不同的预处理? libc++
#ifdef
是否有一些调试代码,如 std::vector
范围检查或设置 -O0 -g
时的东西?
不,只是非常简单的测试,没有任何标准库。有类定义和宏。 Gcc 通常会在预处理步骤中放置很多用于调试的东西(使用 -g)。 (而且我没有意识到 -g 已经影响了预处理,即 .ii 生成并且仍然使用通常的 .ii 文件进行进一步编译)
在 x86-64 Linux 上编译 hello.c
(stdio.h 和使用 printf 的 main()),我得到相同的 gcc -E
输出,有/没有-g
。我试过gcc
和g++
。 gcc7.1。瞄准 Darwin / 它的 libc 而不是 Linux / glibc 时可能会有所不同?以上是关于带有调试选项的 gcc 编译阶段的主要内容,如果未能解决你的问题,请参考以下文章