【gdb】- 观察点调试

本文通过一个实际的C程序调试案例,详细介绍了如何利用gdb的观察点功能来追踪内存异常。在调试过程中,发现了一个由于数组越界导致的诡异问题,虽然无法直接找出问题根源,但通过观察点定位到了异常行为。文章强调了调试复杂问题时,观察点的重要性以及面对未知错误时的挑战。
摘要由CSDN通过智能技术生成
接着上一篇的步骤,经过调试我们知道,虽然sum已经赋了初值0,但仍需要在while (1)循环的开

头加上sum = 0;:

观察点调试实例:

#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;
}

使用scanf函数是非常凶险的,即使修正了这个Bug也还存在很多问题。如果输入的字符串超长了会怎么样?我们知道数组访问越界是不会检查的,所以scanf会写出界。现象是这样的:

[zhangsan@localhost study-c]$ gcc -Wall -g gdb3.c -o gdb3
[zhangsan@localhost study-c]$ ./gdb3
123
input=123
1234
input=1234
12345
input=12345
123456
input=123456
1234567
input=1234567
12345678
input=1912370802

可是奇怪的是当我们输入1234567的时候,字符串也超长了呀,为什么没有错误发生呢?这个问题现在也无法搞清楚?

下面用调试器看看最后这个诡异的结果是怎么出来的:

[zhangsan@localhost study-c]$ gdb gdb3
GNU gdb (GDB) 7.6.1
...
Reading symbols from /home/zhangsan/study-c/gdb3...done.
(gdb) start
Temporary breakpoint 1 at 0x40053c: file gdb3.c, line 5.
Starting program: /home/zhangsan/study-c/gdb3 

Temporary breakpoint 1, main () at gdb3.c:5
5		int sum = 0, i = 0;
(gdb) n
9			sum = 0; 
(gdb) 
10			scanf("%s",input);
(gdb) 
12345678
11			for(i = 0;input[i] != '\0'; i++)
(gdb) print input 
$1 = "12345"

input数组只有5个元素,写出界的是scanf自动添的'\0',用x命令看会更清楚一些:

(gdb) x/10b input 
0x7fffffffe4f0:	49	50	51	52	53	54	55	56
0x7fffffffe4f8:	0	0

x命令打印指定存储单元的内容。10b是打印格式,b表示每个字节一组,10表示打印10组,从input数组的第一个字节开始连续打印10个字节。前8个字节是input数组的存储单元,打印的正是十进制ASCII码的'1'到'8',第9个字节是写出界的'\0'。根据运行结果,前7个字符转成数字都没错,第8个错了,也就是i从0到6的循环

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值