GDB学习:3

来源:互联网 发布:淘宝不退款怎么办 编辑:程序博客网 时间:2024/06/05 10:08

下面看一下观察点调试:

这里的例子如上所示:

#include<stdio.h>int main(void){    int sum = 0, i = 0;    char input[5];    while (1) {        sum = 0;        scanf("%s", input);        for (i = 0; input[i] != '\0'; i++)        sum = sum*10 + input[i] - '0';        printf("input=%d\n", sum);    }    return 0;}
这里输入超长可能就会出现问题:

1234567input=123456712345678input=123456740

下面使用gdb开始调试。
11    int sum = 0, i = 0;(gdb) n14        sum = 0;(gdb) 15        scanf("%s", input);

使用display打印出i以及input的值,这里输入的是12345678:

1234567816        for (i = 0; input[i] != '\0'; i++)1: input = "12345"(gdb) 17        sum = sum*10 + input[i] - '0';1: input = "12345"(gdb) 16        for (i = 0; input[i] != '\0'; i++)1: input = "12345"(gdb) 17        sum = sum*10 + input[i] - '0';1: input = "12345"(gdb) display i2: i = 1(gdb) n16        for (i = 0; input[i] != '\0'; i++)2: i = 11: input = "12345"(gdb) 17        sum = sum*10 + input[i] - '0';2: i = 21: input = "12345"(gdb) 16        for (i = 0; input[i] != '\0'; i++)2: i = 21: input = "12345"(gdb) 17        sum = sum*10 + input[i] - '0';2: i = 31: input = "12345"(gdb) 16        for (i = 0; input[i] != '\0'; i++)2: i = 31: input = "12345"(gdb) 17        sum = sum*10 + input[i] - '0';2: i = 41: input = "12345"

单上这样看不到input周围内存的具体情况,这时可以使用x来打印具体的内存情况:

(gdb) x/10b input 0x7fffffffe010:49505152535455560x7fffffffe018:40
x命令打印存储器中的内容。10b是打印格式,b表示每个字节一组,7表示打印10组  。前8个字节是i也就是i从0到6的循环都没错,我们设一个条件断点从i等于7开始
单步调试:
(gdb) b 17 if i == 7Breakpoint 4 at 0x400592: file watch.c, line 17.(gdb) cContinuing.12345678Breakpoint 4, main () at watch.c:1717        sum = sum*10 + input[i] - '0';2: i = 71: input = "12345"
可见到目前为止虽然数组越界了,但是还没有产生瞠目错误:

(gdb) display sum 3: sum = 1234567
继续单步,可以看到有一位莫名奇妙从7变成了8:

0x7fffffffe010:49505152535455560x7fffffffe018:70(gdb) n17        sum = sum*10 + input[i] - '0';3: sum = 123456782: i = 81: input = "12345"(gdb) x /10 input 0x7fffffffe010:49505152535455560x7fffffffe018:80
为了看清这一位是何时改变的,i可以用观察点(Watchpoint)来跟踪。我们知道断点是当程序执行到某一代码行时中断,而观察点是当程序访问某一存储单元时中断,如果我们不知道某一存储单元是在哪里被改动的,这时候观察点尤其有用。下面删除原来设的断点,从头执行程序,重复上次的输入,用watch命令设置观察点,跟踪input[7]后面那个字节:

(gdb) watch input[8]Hardware watchpoint 8: input[8](gdb) i watchpoints Num     Type           Disp Enb Address            What8       hw watchpoint  keep y                      input[8](gdb) cContinuing.Hardware watchpoint 8: input[8]Old value = 0 '\000'New value = 1 '\001'0x00000000004005b9 in main () at watch.c:1616        for (i = 0; input[i] != '\0'; i++)3: sum = 12: i = 11: input = "12345"(gdb) cContinuing.Hardware watchpoint 8: input[8]Old value = 1 '\001'New value = 2 '\002'0x00000000004005b9 in main () at watch.c:1616        for (i = 0; input[i] != '\0'; i++)3: sum = 122: i = 21: input = "12345"(gdb) cContinuing.Hardware watchpoint 8: input[8]Old value = 2 '\002'New value = 3 '\003'0x00000000004005b9 in main () at watch.c:1616        for (i = 0; input[i] != '\0'; i++)3: sum = 1232: i = 31: input = "12345"(gdb) cContinuing.Hardware watchpoint 8: input[8]Old value = 3 '\003'New value = 4 '\004'0x00000000004005b9 in main () at watch.c:1616        for (i = 0; input[i] != '\0'; i++)3: sum = 12342: i = 41: input = "12345"(gdb) cContinuing.Hardware watchpoint 8: input[8]Old value = 4 '\004'New value = 5 '\005'0x00000000004005b9 in main () at watch.c:1616        for (i = 0; input[i] != '\0'; i++)3: sum = 123452: i = 51: input = "12345"(gdb) cContinuing.Hardware watchpoint 8: input[8]Old value = 5 '\005'New value = 6 '\006'0x00000000004005b9 in main () at watch.c:1616        for (i = 0; input[i] != '\0'; i++)3: sum = 1234562: i = 61: input = "12345"(gdb) cContinuing.Hardware watchpoint 8: input[8]Old value = 6 '\006'New value = 7 '\a'0x00000000004005b9 in main () at watch.c:1616        for (i = 0; input[i] != '\0'; i++)3: sum = 12345672: i = 71: input = "12345"(gdb) cContinuing.Hardware watchpoint 8: input[8]Old value = 7 '\a'New value = 8 '\b'0x00000000004005b9 in main () at watch.c:1616        for (i = 0; input[i] != '\0'; i++)3: sum = 123456782: i = 81: input = "12345"

已经很明显了,每次都是for这句改变了input[5]的值,而且是每次加1,而for这句里的i正是每次加1的,原来input[5]就是i的存储单元,换句话说,i的存储单元是紧跟在input数组后面的。

小结一下上面看到的所有命令:

watch 设置观察点info(或i)watchpoints 查看当前设置了哪些观察点x 从某个位置开始打印存储器的一段内容,全部当成字节来看,而不区分哪些字节属于哪些变量


0 0