(一)g++ -g 添加gdb调试选项
(二)g++ -c 只编译不连接 只生成目标文件 .o文件
(三)g++ -o 指定生成的可执行文件的名称。如果不使用-o选项则会生成默认可执行文件a.out
====华丽的分割线====
下面我们利用不加 -o 选项来编译,并学习下符号表
g++ -g test.cpp 编译test.cpp 将生成目标文件 a.out
示例程序
#include int a = 10;int b;void foo(){static int c = 100;}int main(){int d = 1000;int e;foo();return 0;}
可以看到生成了a.out文件,下面我们用nm -a 命令看下符号表
符号表是编译期产生的一个hash列表,随着可执行文件在一起。符号表包括了变量和函数的信息以及调试信息。
通过readelf -S a.out 可以查看所有符号表头信息
总结如下:
nm和readelf还有很多功能,man可以看下详情。
(1)符号表的生成:
在编译的词法分析的时候,一直向符号表填入符号,例如
有重复定义的时候会报错,因为符号表已经存在该符号了。
(2)符号表的使用:
在连接的时候,链接器会去符号表查找引用的符号是否存在。
对于常量,编译器会向符号表查找const的值,直接替换。
符号表中的调试代码:
所以说区分debug版本和release版本的方法就是看符号表里有没有调试符号了。通过objdump -g a.out 可以看到很多调试信息,符号表在debug模式下是帮助我们调试的利器,release模式下几乎很难去调试。生产上用符号文件调试release程序,我们通常将调试文件放到可执行文件的相同目录,因为gdb会在当前目录查找符号文件,另外可以通过gdb -s 来指定符号文件的位置可以加多个符号文件。我们可以通过attach 加上-s来调试运行中的程序。