gdb查看指针指向数据

示例代码如下:

#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"

  • 13
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值