gdb常用

1.反汇编相关

1.1 设定intel汇编

gdb 默认是att汇编,可通过以下指令进行转换

set disassembly-flavor intel 

从配置文件上进行设置也可以

echo "set disassembly-flavor intel" > ~/.gdbinit

1.2 当前运行代码反汇编

disassemble

1.3 反汇编特定函数

disassemble /m main

/m 可以现实对应的源码

如果在gdb外的话直接使用objdump -S 也是可以看到对应的源码的

1.4 对特定行进行反汇编

先使用info line 找到行对应的汇编地址,比如要找 agora.cpp:308, 看到start address 0x7f51ff963634 和 end address 0x7f51ff963656 , 就是对应的汇编程序段

(gdb) info line agora.cpp:308
Line 308 of "agora.cpp" starts at address 0x7f51ff963634 <rtm_recv_channel_msg(void*, void*)+132> and ends at 0x7f51ff963656 <rtm_recv_channel_msg(void*, void*)+166>

然后使用disassemble 直接查看该段内存(该功能对gdb版本有要求)

disassemble 0x7f51ff963634 0x7f51ff963656 

也可以使用x查看内存的方式进行查看

x/i 0x7f51ff963634 

/i 表示按照指令地址格式

1.5汇编断点

如图想要达到图中的汇编断点处

b *0x7ffff7bd1824
或
b *shm_open+84

*在gdb的brakpoint中似乎不是取值的意思,而是告诉gdb的语法 b *address,一旦解析出*就会把后面的address当作一个地址表达式,计算出其值然后,在那个地址上打断点,没有这个*,gdb会把后面的符号当成一个字符串

1.6 获段寄存器得基址偏移
可参考此处
对于fs寄存器

(gdb) call arch_prctl(0x1003, $rsp - 0x8)    
$2 = 0 
(gdb) x /gx $rsp - 0x8
0x7fffffffe6e8: 0x00007ffff7fe0700   => IA32_FS_BASE

对于gs寄存器

(gdb) call arch_prctl(0x1004, $rsp - 0x8)
$3 = 0 
(gdb) x /gx $rsp - 0x8
0x7fffffffe6e8: 0x0000000000000000   => IA32_GS_BASE

2.layout相关

2.1 layout常用

源码汇编对应调试
layout split 
显示所有寄存器
layout regs
退出layout
ctrl+x a

2.2 layout 详细

layout:用于分割窗口,可以一边查看代码,一边测试。主要有以下几种用法:
layout src:显示源代码窗口
layout asm:显示汇编窗口
layout regs:显示源代码/汇编和寄存器窗口
layout split:显示源代码和汇编窗口
layout next:显示下一个layout
layout prev:显示上一个layout
Ctrl + L:刷新窗口
Ctrl + x,再按1:单窗口模式,显示一个窗口
Ctrl + x,再按2:双窗口模式,显示两个窗口
Ctrl + x,再按a:回到传统模式,即退出layout,回到执行layout之前的调试窗口。

3.内存

3.1 内存查看

格式: x /nfu <addr>
n: 查看的number

x: 是 examine 的缩写

n: 表示要显示的内存单元的个数

f: 表示显示方式, 可取如下值

x 按十六进制格式显示变量。
d 按十进制格式显示变量。(dec)
u 按十进制格式显示无符号整型。(unsigned dec)
o 按八进制格式显示变量。(oct)
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式。 (instruction)
c 按字符格式显示变量。(char)
f 按浮点数格式显示变量。(float)
s 显示地址对应的字符串 (string)

u: 表示一个地址单元的长度:

b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节

3.2 查看指定区域的字符串

x /s 0x7ffff7bd17d0
或
p (char *) 0x7ffff7bd17d0
或者对于一个寄存器
x /s $rbx

3.3 查看指定区域指令

x/i 0x7f51ff963634 

没有添加n和u会有默认值

3.4 查看指定地址中存放的指针

32位指针
(gdb) x /xw 0x555555554f82
0x555555554f82: 0x2f656d6f
64位指针
(gdb) x /xg 0x555555554f82
0x555555554f82: 0x6e6568632f656d6f

3.5 查看指定地址中存放的整数值

(gdb) x /dw 0x555555554f82
0x555555554f82: 123456

3.6 内存查看下的大小端调整

gdb查看的内存的结果都是根据指定的u进行大小端转化过的

比如使用一个w单位去查看一个int类型16进制值的时候, 如下,那么这个值确实就是0x65 6d 6f 68,阅读的时候不用再用脑子做一遍转换了,cpu从内存把四字节的全部加载到寄存器,这个过程做了小端转换到大端

(gdb) x /1xw 0x555555554f81
0x555555554f81:0x65 6d 6f 68

但使用b(单字节)单位查看一个int类型的16进制值的时候, 由于x86平台下内存是默认小端的,显示的结果是由cpu每次将一个单字节的内存加载到寄存器后打印出来,所以结果都要倒着读, 比如说我们查看一个16进制数的时候, 显示如下

(gdb) x /4xb 0x555555554f81
0x555555554f81: 0x68    0x6f    0x6d    0x65

在内存上的排序是从左到右:

0x555555554f81:0x68    
0x555555554f82:0x6f    
0x555555554f83:0x6d    
0x555555554f84:0x65

由于机器是小端,所以这个数是 0x65 6d 6f 68

打印

进制打印

十进制 p /d xxxx, 十六进制 p /x xxx, 二进制 p /t xxx
设置默认的打印格式为16进制 set output-radix 16

打印完整对象

set print pretty on
set print object on;
disable pretty print

特别是disable pretty-printer,高版本gdb的一般做了优化打印,只打印出一些值

ref

1.GDB 单步调试汇编_cnblogs
2.layout 的使用
3.disasemble的使用
4.gdb x的用法
5.gdb x查看大小端

posted @ 2020-04-17 12:44  woder  阅读(620)  评论(0编辑  收藏  举报