首页
社区
课程
招聘
[原创]linux gdb调试方法
发表于: 2022-4-13 19:12 18256

[原创]linux gdb调试方法

2022-4-13 19:12
18256


功能

命令

简写命令

例子

备注

①查看窗口:info win

②切换到src窗口:fs src

③切换到下一个窗口:fs next

①i win

②fs src

③fs n

readelf appName -p .debug_str|grep /

或者

readelf call_update.out -p .debug_str|grep .cpp

调试程序app,并传递参数

gdb app

set args 10

显示传递给main函数的参数

show args

显示源代码,默认10行

list

l

设置断点

①break 文件名:行号

②break 文件名:函数名

③break 行号

③break 函数名

b

例1行号下断点

b main.cpp:6

例2 函数名下断点

b   point.cpp:point::print

设置条件断点

break [break-args] if (condition)

①std::string等于某个值命中断点,这个经过本人验证:

b cppName:20 if strcmp(strName.c_str(),"api-ms") == 0

b cppName:20 if i == 160

b main if argc > 1

b 180 if   (pszName == NULL && i < 0)

b test.c:34 if   (x & y) == 1

b myfunc if i % (j + 3) != 0

⑦b 44 if   strlen(mystring) == 0

设置指定线程的断点

①break <linespec> thread <threadno>

②break   <linespec> thread <threadno> if ...

①break frik.c:13 thread 28 if bartab >   lim

linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID,注意,这个ID是GDB分配的,你可以通过"info   threads"命令来查看

设置内存断点

①watch + [变量][表达式]  当变量或表达式值改变时即停住程序。
  ②rwatch + [变量][表达式] 当变量或表达式被读时,停住程序。
  ③awatch + [变量][表达式] 当变量或表达式被读或被写时,停住程序。

①watch *(int*)0x22cbc0

运行

run

r

整个调试过程,只能运行一次run命令,第二次运行run命令,调试器会询问你是否从新开始调试。如果要运行到下一个断点,不能用run,必须使用continue或者其简写c

运行到下一个断点

continue

c

相当于VS里的F5

运行到下一个断点,输入c,不能输入r,输入run的话会重新开始调试,

单步执行,不能入函数

next

n

相当于vs的F10

单步执行,进入函数

step

s

相当于vs的F11,step/finish组合

跳出函数

finish

相当于vs的Shfit +   F11,函数完整执行后返回,step/finish组合,注意不能使用简写f。f是frame的缩写

跳过当前函数后面的语句直接返回,返回值可以自定义

return 

return 119

step/return组合

查看函数调用堆栈

backtrace

bt

查看设置的断点

info break

i b

注意i和b之间有个空格

查看寄存器的值

info register

i r

注意i和r之间有个空格

查看栈帧信息

①info frame

②info frame 栈帧编号

i f

注意i和f之间有个空格

查看当前stack frame局部变量

info locals

i local

注意不能缩写成i l

删除断点

delete [breakpoints num] [range...]

d

例1:删除序号为5的断点

d 5

例2:删除序号1到4的断点

d 1-4

删除断点(删除指定行的断点,作用范围为1行)

①clear function

②clear   filename:function

③clear   line_number

④clear filename:line_number

禁用断点

disable 断点编号

启用断点

enable 断点编号

打印单个变量值

①print /format 变量名

/x 按十六进制格式显示变量。
  /d 按十进制格式显示变量。
  /u 按十六进制格式显示无符号整型。
  /o 按八进制格式显示变量。
  /t 按二进制格式显示变量。
  /a 按十六进制格式显示变量。
  /c 按字符格式显示变量。
  /f 按浮点数格式显示变量。

p

例1十进制打印nNum:

(gdb) p nNum
  $2 = 100

例2十六进制打印nNum:

(gdb) p /x nNum
  $2 = 0x64

例3计算常量表达式的值:

(gdb) p /x   0x22cb70+0x50

打印数组

p 数组第一个元素@打印长度

p

例1打印int数组的前10个元素:

(gdb) p   nScore[0]@10

例2打印int数组的前10个元素:

(gdb) p   *nScore@10

例3以16进制打印数组前10个元素。

(gdb) p /x   *nScore@10

①set print array 命令,以便能够在显示数组时更方便查看

②如果打印std::string显示不全,可以设置打印的数组元素个数为0,意味着不限制字符个数

set print elements 0   

p  结构体变量a

p  *结构体变量指针




例1:打印结构体变量jack

(gdb) set print null-stop

(gdb) set print pretty

(gdb) p jack


例2:打印结构体变量指针pKevin指向的结构体的内容


(gdb) p *pKevin

例3:打印结构体成员

(gdb) p jack.nId


①set print null-stop 命令,设置字符串的显示规则,即遇到结束符时停止显示

②set print pretty

美观显示

打印内存

打印内存:x  /nfu   addr (以f格式打印n个u类型存储单元的以addr开头的内存值)

格式f: o(octal)  x(hex) d(decimal) u(unsigned decimal)   t(binary) f(float) a(address) i(instruciton) c(char) s(string)

字节u: b(byte)  h(halfword)  w(word)    g(gaint, 8 bytes)

例1:以二进制显示addr处开始的256个字节

x    /256xb addr

例2:以十六进制显示addr处开始的256个字节

x    /256xw addr

1、info display

2、undisplay 常显示变量编号

修改变量的值

set variable key = value
  set var key = value

例1 :修改char数组

set var   chArr="hello lily"

例2:修改int变量

set var nNum=102

例3:修改int数组的某个元素

set var nScore[2]=998

修改并查看变量的值

print 变量名=值

例1:修改并打印char数组

p   chArr="sal"

例2:修改并打印int变量值

p nNum=666

例3:修改并打印int数组的某个元素值

p nScore[0]=666

查看线程信息,并切换线程

info thread

thread 线程编号

i  thread

t 线程编号

显示调用堆栈并切换栈帧、并查看局部变量

bt

frame 栈帧编号

f

①切换到栈帧1

f 1

②查看栈帧1的局部变量

info local

首先使用bt命令显示调用堆栈,

再使用f命令切换栈帧,切换栈帧仅仅是因为gdb没有ui界面,相当于点击vs调用堆栈的某个栈帧。没有发生线程切换

再使用info local查看函数的局部变量。

wh     显示源代码窗口

Ctrl + L  代码窗口清屏(,ctrl+L后按下回车键)

Ctrl + X+ A   退出代码窗口

a)显示所有已经加载的动态库信息

 info shared

b)显示某个已经加载的动态库信息

 info shared libtgcDefender.so

清屏

!clear

(gdb) help dump binary memory

Write contents of memory to a raw binary file.

Arguments are FILE START STOP. Writes the contents of memory

within the range [START .. STOP) to the specified FILE in binary format.



结束调试

quit

q



以下调试源代码:

                                              

(1)开始调试,并设置传递给main函数的参数

命令:gdb 要调试的程序名

set args 参数1  参数2 ......

2)设置、查看断点,并运行命中断点。

  

3)查看并修改变量的值

4)显示指定内存地址的内容


5)单步执行命令n(不进入函数)和s(进入子函数)

6)下断点,并查看断点列表,运行命中断点,切换栈帧并查看局部变量


(7)删除断点

1)查看要调试的程序pid

命令:ps -aux | grep attachDemo


2)附加进程调试

执行gdb attach pid即可调试正在运行的程序,

执行:$ gdb attach 29231,若执行gdb attach时提示:” ptrace: Operation not permitted”,则执行:$ sudo gdb attach 29231

3)在工作者线程中下断点


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2024-1-30 13:53 被sanganlei编辑 ,原因:
收藏
免费 4
支持
分享
最新回复 (2)
雪    币: 4460
活跃值: (6706)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
verygood
2022-4-13 21:57
0
雪    币: 576
活跃值: (2035)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享,mark
2022-4-13 23:42
0
游客
登录 | 注册 方可回帖
返回
//