示例代码如下:
#include<stdio.h>
#include<stdlib.h>
int main()
{
char * p = (char*)malloc(10);
int i = 0;
for (; i < 10; i++)
{
p[i] = i;
}
i = 0;
for (; i < 10; i++)
{
printf("%d ",p[i]);
}
free(p);
return 0;
}
编译命令gcc -g -omain memlook.c然后运行gbd ./main进入调试。
(gdb) list 15
10 }
11 i = 0;
12 for (; i < 10; i++)
13 {
14 printf("%d ",p[i]);
15 }
16 free(p);
17 return 0;
18
19 }
在free(p)处设置断点break 16
(gdb) break 16
Breakpoint 1 at 0x74e: file memlook.c, line 16.
然后运行
(gdb) run
Starting program: /mnt/hgfs/linux/cpp/gdblearn/main
Breakpoint 1, main () at memlook.c:16
16 free(p);
接下来查看指针p指向的数据
方式一:
当需要查看一段连续内存空间的值的时间,可以使用GDB的“@”操作符,“@”的左边是第一个内存地址,“@”的右边则是想查看内存的长度。
int *array = (int *) malloc (len * sizeof (int));
在GDB调试过程中这样显示出这个动态数组的值:
p *array@len
示例:
(gdb) print *p@10
$1 = "\000\001\002\003\004\005\006\a\b\t"
(gdb) print *(char*)p@10
$2 = "\000\001\002\003\004\005\006\a\b\t"
(gdb) print *(int*)p@10
$3 = {50462976, 117835012, 2312, 0, 0, 0, 1041, 0, 540090416, 540221490}
(gdb)
方式二:
我们可以使用examine命令(缩写为x)来查看内存地址中的值。examine命令的语法如下所示:
x/<n/f/u> <addr>
<addr>表示一个内存地址。“x/”后的n、f、u都是可选的参数,n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容;f 表示显示的格式,如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i;u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4字节。u参数可以被一些字符代替:b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指定的内存地址开始,读写指定字节,并把其当作一个值取出来。n、f、u这3个参数可以一起使用,例如命令“x/3uh 0x54320”表示从内存地址0x54320开始以双字节为1个单位(h)、16进制方式(u)显示3个单位(3)的内存。
print的输出格式包括:
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
示例如下:
(gdb) x/10db p
0x555555756260: 0 1 2 3 4 5 6 7
0x555555756268: 8 9
(gdb) x/10dh p
0x555555756260: 256 770 1284 1798 2312 0 0 0
0x555555756270: 0 0
(gdb)
x/10db p 表示查看p指针指向的内存中往后10个地址的数据,并以十进制格式显示变量,以单字节读写指定字节。
(gdb) print *(int*)p
$5 = 50462976
*(int*)p表示将按照整型指针处理。
更多案例:
例子:
main()
{
char *c = "hello world";
printf("%s\n", c);
}
我们在
char *c = "hello world";
下一行设置断点后:
(gdb) l
1 main()
2 {
3 char *c = "hello world";
4 printf("%s\n", c);
5 }
(gdb) b 4
Breakpoint 1 at 0x100000f17: file main.c, line 4.
(gdb) r
Starting program: /Users/songbarry/main
Reading symbols for shared libraries +. done
Breakpoint 1, main () at main.c:4
4 printf("%s\n", c);
可以通过多种方式看C指向的字符串:
方法1:
(gdb) p c
$1 = 0x100000f2e "hello world"
方法2:
(gdb) x/s 0x100000f2e
0x100000f2e: "hello world"
方法3:
(gdb) p (char *)0x100000f2e
$3 = 0x100000f2e "hello world"
将第一个字符改为大写:
(gdb) p *(char *)0x100000f2e='H'
$4 = 72 'H'
再看看C:
(gdb) p c
$5 = 0x100000f2e "Hello world"