Simplestory's Blog

g++与gdb使用

Word count: 1.4kReading time: 5 min
2018/03/02

G++是Unix/Linux下C++的编译器,gdb则是Unix/Linux下有力的调试工具。大多数时候,我们编写的C/C++代码并不是运行在Windows上,而是在Linux系统上跑。这里我记录了一些有关于g++和gdb的一些使用方法以备不时之需。

g++的使用

g++在执行编译工作的时候,总共需要4步:

  • 预处理,生成.i的文件,主要是头文件和宏定义的展开:g++ -E test.cpp -o test.i
  • 编译,将预处理后的文件转换成汇编语言,生成文件.s: g++ -S test.i -o test.s
  • 汇编,有汇编变为目标代码(机器代码)生成.o的文件,主要是将.s文件转为二进制文件: g++ -c test.s -o test.o
  • 链接,连接目标代码,生成可执行程序: g++ test.o -o test

以上步骤也可以用一条命令解决:

g++ test.cpp -o test

当涉及多个文件的编译时,有以下两种做法:

1
2
3
4
5
6
$ g++ a.cpp b.cpp c.cpp -o test  #一次性编译所有文件

$ g++ a.cpp -o a.o #分开编译
$ g++ b.cpp -o b.o
$ g++ c.cpp -o c.o
$ g++ a.o b.o c.o -o test

这里建议采用分开编译的方法,这样当你对其中一个或多个文件进行修改时,只需要对应的编译那一个或多个文件,而不需要从头开始编译。


常用的g++选项:

命令 描述
-Wall 编译时输出一些警告和错误信息
-c 只编译不连接
-E 对源文件进行预处理
-S 将预处理后的文件转为汇编文件
-o 指定输出文件名
-I 指定一个包含头文件的路径
-l 指定一个附加库
-L 指定一个附加的库路径
-shared 生成动态库文件

Linux下文件的类型是不依赖于其后缀名的,但一般来讲: .o是目标文件,相当于windows中的.obj文件 .so为共享库,是shared object,用于动态连接的,和.dll差不多 .a为静态库,是好多个.o合在一起,用于静态连接 .la为libtool自动生成的一些共享库,主要记录了一些配置信息。

gdb的使用

.cpp在编译时要加上-g选项,生成的可执行文件才能用gdb进行源码级调试

g++ -g test.cpp -o test

值得注意的是,-g分4个等级:

  • g0等于不加-g。即不包含任何信息
  • g1只包含最小信息,一般来说只有你不需要debug,只需要backtrace信息,并且真的很在意程序大小,或者有其他保密/特殊需求时才会使用-g1。
  • g2为gdb默认等级,包含绝大多数你需要的信息。
  • g3包含一些额外信息,例如包含宏定义信息。当你需要调试宏定义时,请使用-g3

一般来说,gdb主要帮助你完成下面四个方面的功能:

  1. 启动程序,可以按照自定义的要求运行程序。

  2. 可以让调试程序在指定的位置的断点处停止。

  3. 当程序停止时,可以检查此时程序中所发生的事情。

  4. 动态的改变程序的执行环境。

几种方法在gdb下运行程序:

  • gdb ${程序} 进入gdb后,输入run(简写r) ${arg1} ${arg2} … ${argN}
  • gdb --args ${程序} ${arg1} ${arg2} … ${argN}进入gdb后,运行run
  • 进入gdb后,输入file ${程序}。然后使用set args ${arg1} ${arg2} … ${argN}设定好程序参数,再运行run

常用gdb调试命令:

命令 描述
start 开始执行程序,停在主函数第一行语句前面
backtrace/bt 查看各级函数调用,显示栈信息
step/s 单步调试,步入当前函数
next/n 单步调试,步过当前函数
until/u 执行到当前循环完成
continue/c 继续运行程序
finish 执行到当前函数返回
list/l 列出源代码,一次10行
list <行号> 列出从第几行开始的源代码
list <函数名> 列出函数源代码
print/p <表达式> 打印表达式的值
frame/f x 切换到第x帧,其中x会在bt命令中显示,从0开始,0表示栈顶
up/down x 往栈顶/栈底移动x帧,当不输入x时,默认为1
info/i locals 打印当前栈帧的本地变量
set var x 修改当前x变量的值
break <行号> 源文件指定行号设置断点
break <函数名> 源文件指定函数设置断点
break <行号/函数名> if <条件> 设置条件断点,满足条件时则在设置处断开
watch <变量> 写监视指定变量,当变量发生变化时停止程序运行
rwatch <变量> 读监视指定变量,当变量被读取时停止程序运行
awatch <变量> 读写监视指定变量,当变量发生变化或被读取时程序停止运行
delete <行号/函数名> 删除断点
info/i b 查看断点信息
save breakpoint <文件名>.dp 断点保存在指定文件中
-x <文件名>.dp 该选项读取指定文件,恢复文件中的断点设置
quit 退出gdb调试

致谢

macky0668——linux下c++的编译器g++的基本使用

爱折腾的西山居士——GDB常用命令系列

改变自己chenyu——linux之gdb基本调试命令和使用总结

gdb 调试入门,大牛写的高质量指南

CATALOG
  1. 1. g++的使用
  2. 2. gdb的使用
  3. 3. 致谢