GDB学习:3
2016-01-14 10:31
363 查看
下面看一下观察点调试:
这里的例子如上所示:
下面使用gdb开始调试。
使用display打印出i以及input的值,这里输入的是12345678:
单上这样看不到input周围内存的具体情况,这时可以使用x来打印具体的内存情况:
单步调试:
已经很明显了,每次都是for这句改变了input[5]的值,而且是每次加1,而for这句里的i正是每次加1的,原来input[5]就是i的存储单元,换句话说,i的存储单元是紧跟在input数组后面的。
小结一下上面看到的所有命令:
这里的例子如上所示:
#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; }这里输入超长可能就会出现问题:
1234567 input=1234567 12345678 input=123456740
下面使用gdb开始调试。
11 int sum = 0, i = 0; (gdb) n 14 sum = 0; (gdb) 15 scanf("%s", input);
使用display打印出i以及input的值,这里输入的是12345678:
12345678 16 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 i 2: i = 1 (gdb) n 16 for (i = 0; input[i] != '\0'; i++) 2: i = 1 1: input = "12345" (gdb) 17 sum = sum*10 + input[i] - '0'; 2: i = 2 1: input = "12345" (gdb) 16 for (i = 0; input[i] != '\0'; i++) 2: i = 2 1: input = "12345" (gdb) 17 sum = sum*10 + input[i] - '0'; 2: i = 3 1: input = "12345" (gdb) 16 for (i = 0; input[i] != '\0'; i++) 2: i = 3 1: input = "12345" (gdb) 17 sum = sum*10 + input[i] - '0'; 2: i = 4 1: input = "12345"
单上这样看不到input周围内存的具体情况,这时可以使用x来打印具体的内存情况:
(gdb) x/10b input 0x7fffffffe010: 49 50 51 52 53 54 55 56 0x7fffffffe018: 4 0x命令打印存储器中的内容。10b是打印格式,b表示每个字节一组,7表示打印10组 。前8个字节是i也就是i从0到6的循环都没错,我们设一个条件断点从i等于7开始
单步调试:
(gdb) b 17 if i == 7 Breakpoint 4 at 0x400592: file watch.c, line 17. (gdb) c Continuing. 12345678 Breakpoint 4, main () at watch.c:17 17 sum = sum*10 + input[i] - '0'; 2: i = 7 1: input = "12345"可见到目前为止虽然数组越界了,但是还没有产生瞠目错误:
(gdb) display sum 3: sum = 1234567继续单步,可以看到有一位莫名奇妙从7变成了8:
0x7fffffffe010: 49 50 51 52 53 54 55 56 0x7fffffffe018: 7 0 (gdb) n 17 sum = sum*10 + input[i] - '0'; 3: sum = 12345678 2: i = 8 1: input = "12345" (gdb) x /10 input 0x7fffffffe010: 49 50 51 52 53 54 55 56 0x7fffffffe018: 8 0为了看清这一位是何时改变的,i可以用观察点(Watchpoint)来跟踪。我们知道断点是当程序执行到某一代码行时中断,而观察点是当程序访问某一存储单元时中断,如果我们不知道某一存储单元是在哪里被改动的,这时候观察点尤其有用。下面删除原来设的断点,从头执行程序,重复上次的输入,用watch命令设置观察点,跟踪input[7]后面那个字节:
(gdb) watch input[8] Hardware watchpoint 8: input[8] (gdb) i watchpoints Num Type Disp Enb Address What 8 hw watchpoint keep y input[8] (gdb) c Continuing. Hardware watchpoint 8: input[8] Old value = 0 '\000' New value = 1 '\001' 0x00000000004005b9 in main () at watch.c:16 16 for (i = 0; input[i] != '\0'; i++) 3: sum = 1 2: i = 1 1: input = "12345" (gdb) c Continuing. Hardware watchpoint 8: input[8] Old value = 1 '\001' New value = 2 '\002' 0x00000000004005b9 in main () at watch.c:16 16 for (i = 0; input[i] != '\0'; i++) 3: sum = 12 2: i = 2 1: input = "12345" (gdb) c Continuing. Hardware watchpoint 8: input[8] Old value = 2 '\002' New value = 3 '\003' 0x00000000004005b9 in main () at watch.c:16 16 for (i = 0; input[i] != '\0'; i++) 3: sum = 123 2: i = 3 1: input = "12345" (gdb) c Continuing. Hardware watchpoint 8: input[8] Old value = 3 '\003' New value = 4 '\004' 0x00000000004005b9 in main () at watch.c:16 16 for (i = 0; input[i] != '\0'; i++) 3: sum = 1234 2: i = 4 1: input = "12345" (gdb) c Continuing. Hardware watchpoint 8: input[8] Old value = 4 '\004' New value = 5 '\005' 0x00000000004005b9 in main () at watch.c:16 16 for (i = 0; input[i] != '\0'; i++) 3: sum = 12345 2: i = 5 1: input = "12345" (gdb) c Continuing. Hardware watchpoint 8: input[8] Old value = 5 '\005' New value = 6 '\006' 0x00000000004005b9 in main () at watch.c:16 16 for (i = 0; input[i] != '\0'; i++) 3: sum = 123456 2: i = 6 1: input = "12345" (gdb) c Continuing. Hardware watchpoint 8: input[8] Old value = 6 '\006' New value = 7 '\a' 0x00000000004005b9 in main () at watch.c:16 16 for (i = 0; input[i] != '\0'; i++) 3: sum = 1234567 2: i = 7 1: input = "12345" (gdb) c Continuing. Hardware watchpoint 8: input[8] Old value = 7 '\a' New value = 8 '\b' 0x00000000004005b9 in main () at watch.c:16 16 for (i = 0; input[i] != '\0'; i++) 3: sum = 12345678 2: i = 8 1: input = "12345"
已经很明显了,每次都是for这句改变了input[5]的值,而且是每次加1,而for这句里的i正是每次加1的,原来input[5]就是i的存储单元,换句话说,i的存储单元是紧跟在input数组后面的。
小结一下上面看到的所有命令:
watch 设置观察点 info(或i) watchpoints 查看当前设置了哪些观察点 x 从某个位置开始打印存储器的一段内容,全部当成字节来看,而 不区分哪些字节属于哪些变量
相关文章推荐
- 类String的详细介绍类引用
- 使用Git命令从Github下载代码仓库
- OpenCV入门指南】第十二篇 在Windows平台下分享OpenCV程序
- javascript笔记——jqGrid 格式化时间列
- 用java解析在OpenStreetMap上下载的地图数据(SAX版,适合比较大的xml文件)
- SQL Server把一台服务器上的数据库转移到另外一台服务器上。而转移完成后,需要给一个"登录"关联一个"用户"时,发生错误:“错误15023:当前数据库中已存在用户或角色”或“用户、组或角色 在当前数据库中已存在”
- HDFS+MapReduce+Hive+HBase十分钟快速入门
- fastjson使用(九) -- JSONPath使用
- C# 简单的泛型单例
- 网络编程websocket
- 在论坛中出现的比较难的sql问题:46(日期条件出现的奇怪问题)
- Django开发博客(七)——markdown优化
- InterruptedException
- Android支持库——RenderScript
- 【OpenCV入门指南】第十一篇 鼠标绘图
- 使用 InstallShield limited edition 打包部署Outlook 2013 Office add-in插件
- Mac OS
- 如何使用 Python 创建一个 NBA 得分图?
- Thread实现接口 Runnable
- Goolge Map API 源码