一、背景
gdb是一款强大的命令行调试工具,可以形成执行程序、脚本。只需要几个简单的命令,就能够实现Windows环境下VC等IDE的图形化调式工具的功能。
调试的相关常识:
- 程序的发布方式有两种,
debug
模式和release
模式; - Linux
gcc/g++
出来的二进制程序,默认是release
模式; - 要使用gdb调试,必须在源代码生成二进制程序的时候,加上
-g
选项。
gdb的功能:
- 启动程序时,能够按照开发者自定义的要求随心所欲的运行程序;
- 可以让调试程序在开发者指定的位置的断点处停止;
- 当程序停止时,可以检查此时程序中发生的事;
- 动态改变程序的执行环境。
二、gdb的参数
2.1 案例分析
为了更好地说明gdb的调试,使用c++源程序test.cpp进行案例分析,详见下列代码。
1 #include<iostream>
2 using namespace std;
3
4 int addToTop(int top)
5 {
6 cout<<"enter addToTop"<<endl;
7
8 int sum = 0;
9 for(int i = 0;i<=top;i++)
10 {
11 sum += i;
12 }
13 cout<<"quit addToTop"<<endl;
14 return sum;
15 }
16
17
18 int main()
19 {
20 int top = 100;
21 int result = addToTop(top);
22 cout<<"result: "<<result<<endl;
23 return 0;
24 }
创建建文件Makefile
,生成自动化构建工具。在调试C/C++程序,首先在编译时,我们必须要把调试信息加到可执行文件中,使用编译器(gcc/g++)的-g
参数可以做到这点:
1 mytest:test.cpp
2 g++ -o mytest test.cpp -g -std=c++11 //如果没有-g,将看不见程序的函数名、变量名
3 .PHONY:clean
4 clean:
5 rm -f mytest
**g++**编译生成可执行文件mytest
:
使用gdb调试的启动方法:
//启动gdb方法1
gdb <program>
//<program>表示可执行程序,一般在当前目录下
//启动gdb方法2
gdb <program>core
//用gdb同时调试一个运行程序和core文件,core文件是程序非法执行后core dump产生的文件
//启动gdb方法3
gdb <program> <PID>
//若启动的程序是一个服务程序,那么可以指定这个程序运行时的进程PID。
这里我么使用方法1进行案例分析。
readlf
命令常用于对可执行程序的分析,具体语法如下:
readelf -S
readlf
这里不作说明,后续会详解。使用命令list或l
随机列出10行代码:
若l
命令后接数字,则规定了从哪一行开始展示接下来的10行代码:
此外,gdb会记住最近的位置,直接回车表示即可。
run或r
命令表示运行程序:
break或b
命令设置断点,下图在源程序第19行处设置断点;info b
查看断点信息。
当前断点的编号,不能接行号
断点的编号依次递增
下图中,r
运行程序后在源程序第20行处停住,next或n
命令执行但语句
print或p
命令。打印局部变量sum的值:
而continu
命令则继续运行程序
2.2 gdb常用参数
gdb退出使用 ctrl+d或quit调试命令;
list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行;
list/l 函数名:列出某个函数的源代码;
r或run:运行程序(开始调试);
n或next:单条执行;
s或step:进入函数调用;
break(b)行号:在某一行设置断点;
enable:开启断点;
disable:关闭断点;
delete breakpoint:删除所有断点;
delete breakpoint n:删除序号为n的断点;
info break(b):查看断点信息;
print§:打印表达式的值,通过表达式可以修改变量的值或调用函数;
p 变量:打印变量值;
set var:修改变量的值;
display:常显示(内置类型、结构体等自定义类型,stl),追踪查看一个变量,每次停下来都显示它的值;
undisplay:取消常显示(取消对先前设置的哪些变量的追踪);
until 行号:在函数内,进行指定位置跳转,执行完区间代码;
finish:进入一个函数,只执行完该函数,就停下来;
c或continue:从一个断点处,直接运行到下一个断点处;
breaktrace(或bt):查看各级函数调用及参数;
info (i) locals:查看当前栈帧局部变量的值。
不积跬步,无以至千里;不积小流,无以成江海。