gdb中利用examine命令(简写是x)对内存进行监测
一.使用的测试代码
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
struct node
{
char a;
short b;
int c;
};
int main(int argc, char const* argv[])
{
struct node s;
//cout<<sizeof(s)<<endl;
memset(&s, 0, sizeof(s));
s.a = 3;
s.b = 5;
s.c = 7;
printf("%c\n", s.a);
struct node* pt = &s;
printf("%d\n", *(int*)pt);
printf("%lld\n", *(long long*)pt);
return 0;
}
二.x命令
1.帮助文档上的阐述
(gdb) help x
Examine memory: x/FMT ADDRESS.
ADDRESS is an expression for the memory address to examine.
FMT is a repeat count followed by a format letter and a size letter.
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
t(binary), f(float), a(address), i(instruction), c(char) and s(string).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
The specified number of objects of the specified size are printed
according to the format.
Defaults for format and size letters are those previously used.
Default count is 1. Default address is following last thing printed
with this command or "print".
2.详细叙述
2.1格式
x/<n/f/u> <addr>
n、f、u是可选的参数
(1) n 是一个正整数,表示需要显示的内存单元的个数,也就是说从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义。
(2) u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。
u参数可以用下面的字符来代替,
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节。
当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。
**************************************************
注意:严格区分n和u的关系,n表示单元个数,u表示每个单元的大小。
**************************************************
(3)f 表示显示的格式,参见下面。如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i。
一般来说,GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。例如,你想输出一个整数的十六进制,或是二进制来查看这个整型变量的中的位的情况。要做到这样,你可以使用GDB的数据显示格式:
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
2.2举例
命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示输出三个单位,u表示按十六进制显示。
3.测试
(gdb) x/2tw &s
0x7fffffffde70: 00000000000001010000000000000011 00000000000000000000000000000111
(gdb) x/4uh &s
0x7fffffffde70: 3 5 7 0
(gdb) p &s.a
$4 = 0x7fffffffde70 "\003"
(gdb) p &s.b
$5 = (short *) 0x7fffffffde72
(gdb) p &s.c
$6 = (int *) 0x7fffffffde74
(gdb) x/4th &s
0x7fffffffde70: 0000000000000011 0000000000000101 0000000000000111 0000000000000000
(gdb) x/8tb &s
0x7fffffffde70: 00000011 00000000 00000101 00000000 00000111 00000000 00000000 00000000
(gdb)
可以看到当代码执行完s.c = 7
时,监视此时s地址的内存情况:
从地址0x7fffffffde70开始,由于是小端机器,数据的低位对应地址的低位,由左往右依次是3,5,7的二进制表示形式,由于结构体中出现了内存对齐,所以出现了总共8个字节,64位才能看到内存所保存的所有数据
图示:
0x7fffffffde72 0x7fffffffde70
5 3
0x7fffffffde74
7
地址高位 地址低位
数据高位 数据低位
<------------------------------------
0000000000000101 0000000000000011
0000000000000000 0000000000000111
由于printf打印时,是由地址高位向低位打印,所以结果是:
[root@fundation10 Linux兴趣小组]# ./t
327683
30065098755
转换成二进制即是
1010000000000000011
11100000000000001010000000000000011