> 文章列表 > Linux下程序调试的方法【GDB】GDB相关命令和基础操作(命令收藏)

Linux下程序调试的方法【GDB】GDB相关命令和基础操作(命令收藏)

Linux下程序调试的方法【GDB】GDB相关命令和基础操作(命令收藏)

目录

1、编译

2、启动gdb调试

2.1 直接运行

2.2 运行gdb后使用run命令

2.3 调试已运行的程序

3、图形界面提示

4、调试命令

1、查看源码

2、运⾏程序/查看运⾏信息

3、设置断点

5、单步/跳步执⾏

6、分割窗口

7、其他命令

8、相关参数


1、编译

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

-g选项的作用是在可执行文件中加入源代码的倍息,比如可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb能找到源文件。

g也是分级别的,-g分4个等级:

选项 解析
g0 等于不加-g;即不包含任何信息
g1 级别1(-g1)不包含局部变量和与行号有关的调试信息,因此只能够用于回溯跟踪和堆栈转储之用。回溯跟踪指的是监视程序在运行过程中的函数调用历史,堆栈转储则是一种以原始的十六进制格式保存程序执行环境的方法,两者都是经常用到的调试手段
g2 这是默认的级别,此时产生的调试信息包括扩展的符号表、行号、局部或外部变量信息
g3 包含级别2中的所有调试信息,以及源代码中定义的宏

首先用 gcc 对代码进行编译,生成可执行文件 test 

$ gcc test.c -g -o test

2、启动gdb调试

GDB 主要有3种调试功能:

gdb program:使用GDB 开始执行被调试程序program,可通过GDB 命令控制program 的行为;

gdb program core:使用GDB 同时执行被调试程序program 和core 文件(程序异常中止或退出时,保存的内存映像加调试信息文件,包含程序当前的内存、寄存器、堆栈等信息),便于定位分析程序异常中止或退出的原因;
gdb attach PID (gdb -p PID):使用GDB 接管(attach)一个正在运行的被调试程序,PID 为被调试程序的process-ID(可通过pidof program 查看),可通过GDB 命令控制program 的行为。
 

2.1 直接运行

gdb test//最常用的用gdb启动程序,开始调试的方式gdb test core //用gdb查看core dump文件,跟踪程序core的原因gdb --args test arg1 arg2//带参数的程序调试

2.2 运行gdb后使用run命令

//无参数
gdb test
run 
//参数
gdb test
run arg1 arg2

2.3 调试已运行的程序

sudo gdb program pid //用gdb调试已经开始运行的程序,指定pid即可
sudo gdb attach pid //用gdb调试已经开始运行的程序,指定pid即可

3、图形界面提示

将上述命令的gdb换成gdbtui会显示出图形提示界面

输入:

gdbtui mytest

显示出在第9行打了断点


 

4、调试命令

1、查看源码

list(简写l)

查看程序源代码,默认显⽰10⾏,回车翻页

ist ⾏号

将显⽰当前⽂件以“⾏号”为中⼼的前后10⾏代码,如,list 12

list 函数名

将显⽰“函数名”所在函数的源代码,如,list main

list

不带参数,将接着上⼀次 list 命令的,输出下边的内容

2、运⾏程序/查看运⾏信息

run(简写r)

运⾏程序直到遇到 结束或者遇到断点等待下⼀个命令

where/bt

当前运⾏的堆栈列表

bt backtrace

显⽰当前调⽤堆栈

up/down

改变堆栈显⽰的深度

set args

指定运⾏时的参数

show args

查看设置好的参数

info program

来查看程序的是否在运⾏,进程号,被暂停的原因

i breakpoint    

显示当前断点列表

i reg[ister]    

显示寄存器信息

i threads    

显示线程信息

i func    

显示所有的函数名

i local    

显示当前函数的所有局部变量的信息

i prog    

显示调试程序的执行状态

i watch exp    

为表达式(变量)exp设置一个观察点。一但表达式值有变化时,马上停住程序。

i proc    

显示进程的概要信息

info proc mappings     

报告你进程所能访问的地址范围。

info proc times    

你进程和子进程的开始时间,用户时间(user CPU time),和系统CPU时间。

info proc id    

报告有关进程id的信息

info proc status    

报告你进程的一般状态信息。如果进程停止了。这个报告还包括停止的原因和收到的信号

info proc all    

显示上面proc命令这些命令返回的所有信息

其他info命令

info  thread

列出线程

info  register

列出寄存器

info  frame

列出栈帧

info  files

列出当前文件

info  share

列出当前共享库

i breakpoint    

显示当前断点列表

i reg[ister]    

显示寄存器信息

i threads    

显示线程信息

i func    

显示所有的函数名

i local    

显示当前函数的所有局部变量的信息

i prog    

显示调试程序的执行状态

i watch exp    

为表达式(变量)exp设置一个观察点。一但表达式值有变化时,马上停住程序。

i proc    

显示进程的概要信息

info proc mappings     

报告你进程所能访问的地址范围。

info proc times    

你进程和子进程的开始时间,用户时间(user CPU time),和系统CPU时间。

info proc id    

报告有关进程id的信息

info proc status    

报告你进程的一般状态信息。如果进程停止了。这个报告还包括停止的原因和收到的信号

info proc all    

显示上面proc命令这些命令返回的所有信息

3、设置断点

break(简写b)

b ⾏号---  在某⾏设置断点

b address---  在地址address上设置断点
b function---    此命令用来在某个函数上设置断点,在进入指定函数时停住
b linenum---    在行号为linenum的行上设置断点。程序在运行到此行之前停止
b +offset/b -offset---    在当前程序运行到的前几行或后几行设置断点。offset为行号
b filename:linenum---   在文件名为filename的原文件的第linenum行设置断点
b filename:function---    在文件名为filename的原文件的名为function的函数上设置断点。当你的多个文件中可能含有相同的函数名时必须给出文件名

break---       break命令没有参数时,表示在下一条指令处停住。

info breakpoints

显⽰断点信息

b fn1 if a>b

条件断点设置

break func(break缩写为b)

在函数func()的⼊⼝处设置断点,如break cb_button

delete 断点号n

删除第n个断点

disable 断点号n

暂停第n个断点

enable 断点号n

开启第n个断点

clear ⾏号n

清除第n⾏的断点

delete breakpoints

清除所有断点

删除所有断点 (gdb) delete

Num

断点编号

Disp

断点执⾏⼀次之后是否有效 kep:有效    dis :⽆效

Enb

当前断点是否有效

Address

内存地址

What

位置

5、单步/跳步执⾏

使⽤ continue、step、next命令

continue(简写 c)

继续执⾏程序,直到下⼀个断点或者结束;

next(简写 n )

单步执⾏程序,但是遇到函数时会直接跳过函数,不进⼊函数;

step(简写 s)

单步执⾏程序,但是遇到函数会进⼊函数;    

s [n] ---   n为步进次数。如果调用了某个函数,会跳入函数内部。

until

当你厌倦了在⼀个循环体内单步跟踪时,这个命令可以运⾏程序直到退出循环体;

until+⾏号

运⾏⾄某⾏,不仅仅⽤来跳出循环;

finish

 运⾏程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息;

6、查看变量
使⽤print、whatis命令

print 表达式

简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,⽐如当前正在调试C语⾔的程序,那么“表达式”可以是任何C语⾔的有效表达式,包括数字,变量甚⾄是函数调⽤。

p/fmt exp fmt为以下值
x 十六进制    d 十进制
u 无符号数    o 八进制
t 二进制      a 十六进制打印
c 字符格式    f 浮点数

print a

将显⽰整数 a 的值

print ++a

将把 a 中的值加1,并显⽰出来

print name

将显⽰字符串 name 的值

print gdb_test(22)

将以整数22作为参数调⽤ gdb_test() 函数

print gdb_test(a)

将以变量 a 作为参数调⽤ gdb_test() 函数

display 表达式

在单步运⾏时将⾮常有⽤,使⽤display命令设置⼀个表达式后,它将在每次单步进⾏指令后,紧接着输出被设置的表达式及值。如display a

watch 表达式

设置⼀个监视点,⼀旦被监视的“表达式”的值改变,gdb将强⾏终⽌正在被调试的程序。如watch a

whatis

查询变量或函数

info function

查询函数

info locals

显⽰当前堆栈页的所有变量

call 函数(参数)

调⽤程序中可见的函数,并传递“参数”,如,call gdb_test(55);

6、分割窗口

layout

⽤于分割窗⼝,可以⼀边查看代码,⼀边测试

layout src

显⽰源代码窗⼝

layout asm

显⽰反汇编窗⼝

layout regs

显⽰源代码/反汇编和CPU寄存器窗⼝

layout split

显⽰源代码和反汇编窗⼝

Ctrl + L

刷新窗⼝

7、其他命令

命令 描述
file [filename] 装入想要调试的可执行文件
kill [filename] 终止正在调试的程序
break [file:]function 在(file文件的)function函数中设置一个断点
clear 删除一个断点,这个命令需要指定代码行或者函数名作为参数
run [arglist] 运行您的程序 (如果指定了arglist,则将arglist作为参数运行程序)
bt Backtrace: 显示程序堆栈信息
print expr 打印表达式的值
continue 继续运行您的程序 (在停止之后,比如在一个断点之后)
list 列出产生执行文件的源代码的一部分
next 单步执行 (在停止之后); 跳过函数调用
nexti 执行下一行的源代码中的一条汇编指令
set 设置变量的值。例如:set nval=54 将把54保存到nval变量中
step 单步执行 (在停止之后); 进入函数调用
stepi 继续执行程序下一行源代码中的汇编指令。如果是函数调用,这个命令将进入函数的内部,单步执行函数中的汇编代码
watch 使你能监视一个变量的值而不管它何时被改变
rwatch 指定一个变量,如果这个变量被读,则暂停程序运行,在调试器中显示信息,并等待下一个调试命令。参考rwatch和watch命令
awatch 指定一个变量,如果这个变量被读或者被写,则暂停程序运行,在调试器中显示信息,并等待下一个调试命令。参考rwatch和watch命令
Ctrl-C 在当前位置停止执行正在执行的程序,断点在当前行
disable 禁止断点功能,这个命令需要禁止的断点在断点列表索引值作为参数
display 在断点的停止的地方,显示指定的表达式的值。(显示变量)
undisplay 删除一个display设置的变量显示。这个命令需要将display list中的索引做参数
enable 允许断点功能,这个命令需要允许的断点在断点列表索引值作为参数
finish 继续执行,直到当前函数返回
ignore 忽略某个断点制定的次数。例:ignore 4 23 忽略断点4的23次运行,在第24次的时候中断
info [name] 查看name信息
load 动态载入一个可执行文件到调试器
xbreak 在当前函数的退出的点上设置一个断点
whatis 显示变量的值和类型
ptype 显示变量的类型
return 强制从当前函数返回
txbreak 在当前函数的退出的点上设置一个临时的断点(只可使用一次)
make 使你能不退出 gdb 就可以重新产生可执行文件
shell 使你能不离开 gdb 就执行 UNIX shell 命令
help [name] 显示GDB命令的信息,或者显示如何使用GDB的总体信息
quit 退出gdb

8、相关参数

参数 解析
gdb -e 指定可执行文件名
gdb -c 指定coredump文件
gdb -d 指定目录加入到源文件搜索路径
gdb –cd 指定目录作为路径运行gdb
gdb -s 指定文件读取符号表
gdb -p 指定attach进程