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:40x命令打印存储器中的内容。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
- GDB学习:3
- gdb学习
- GDB学习
- gdb学习
- 学习GDB
- GDB学习
- gdb学习
- GDB学习
- gdb学习
- GDB学习
- GDB学习
- gdb学习
- 学习GDB
- Linux 学习第3天 gdb 学习
- [GDB-7] gdb 的学习
- 学习--GDB调试
- 开始学习gdb
- gdb 学习资料
- Android 进程间通信的几种实现方式
- SQLite升级数据库时修改表字段,如何保留以前的数据
- 在Eclipse中使用JUnit4进行单元测试(初级篇)
- Intent基本使用
- 论 关键字 volatile
- GDB学习:3
- shell 点滴 “/bin/sh^M: bad interpreter: No such file or directory。”
- Mac环境整理的一些命令及快捷键
- IOS SWIFT 简单操作文件
- 数字图像处理基础(十一)---缩放、角度旋转和仿射变换及代码实现
- action recognition 特征表达- Cuboid,stip
- IOS面试题 ios笔试题 带答案
- 时间转换
- 认真做人 认真做事