您的位置:首页 > 其它

写程序的一些Debug总结

2013-09-05 17:37 232 查看

写在前面:

写程序,难免要遇到大大小小的bug,没有思路时常常令码友们头疼不已,寝室难安。然而有些bug总要自己经历过一次才会印象深刻,就像我们可能很多人都去读《C陷阱与缺陷》,但是过不几日就淡忘了。不管初级程序员,还是入行很久资深程序员,可能遇到的bug都是些很低级的错误,只要稍加细心就可避免。人非圣贤,出错总避免不了, 这里把自己曾经经历的具有典型性的bug处理整理一下,日后遇到类似的bug,希望可以提供一些调试的思路。
不得不感叹,语言只是一种工具,真正体现价值的还是你的思维。

问题1:

1、如下图1。遇到的问题:if中的判断明明是正确的,但是单步调试的时候就是不执行if下面的代码。
调试分析:等于符号”==”左边的表达式没有加括号,又因为”==”比”&”的优先级高,所以程序先判断等于,再执行”&”,偏离了作者本来的想法,于是便出错了。
解决方法:给等于符号”==”左边的表达式加上括号()。
思维扩展:注意用其他运算符时加上括号,防止优先级问题带来不必要的困扰。不要吝啬小括号。



图1

问题2:

2、如下图2。遇到的问题:err的返回码总是错误,即使发送信号量的代码放到等待接收信号量的代码前面,返回的错误码也总不为OS_NO_ERR。
调试分析:查看信号量相关的宏定义发现value是uint16型的,而定义的信号量TCP_STATUS_OK却是uint32型的,会不会是所占空间大小不同判定信号量时诗句溢出了呢。
解决方法:将定义信号量宽度的代码#define OS_FLAGS_NBITS 16u改为#define OS_FLAGS_NBITS 32u。即将信号量的value值改为uint32型的,再去测试,程序顺利通过。
思维扩展:注意有关联的数据类型的匹配,防止数据溢出。



图2

问题3:

3、如下图3。遇到的问题:程序的意思是给数组time的第四个元素time[3]赋一个值,然后把数组time中的数据copy到另一个数组中,用的是一个CpyDataToArray()的一个函数,这个函数是先用strlen函数得到time的长度,然后依次把time中的元素copy过去。调试的时候发现copy后的值后面总会多一个退格符‘/b‘或者别的符号。

调试分析:strlen()是检测‘/0‘来确定数组长度的,time数组开了四个元素的空间,赋了四个值,结束符’/0‘没地方存放了 导致strlen()函数贩毒案数组长度的时候出错。

解决办法:给数组time多开辟一个字节的空间,即将time[4]改成time[5],问题解决。

思维拓展:在开辟数组存储数据的时候,记得多开辟几个字节的空间,内存溢出的错误很蹊跷的!!!



图3

问题4:

4.如图4所示。关于这个描述起来很混乱。我只想说:注意优先级的问题啊,括号的优先级大于成员选择“.”的优先级,血淋淋的教训啊!!!!!!



图4

问题5:

5.如图5所示。再碰见类似的问题的时候,就想想是不是忘了对调用的外部函数进行声明吧。。。



图5

问题6:

6.问题描述:最近遇到一个问题,同样的一段代码,在我自己用的板子上可以,烧录到别的板子上就不行,运行不了几行就直接进入的hard_fault异常。于是怀疑硬件,但是硬件运行别的程序就没有问题。于是乎,陷入了不知从何处下手的纠结。

问题分析:此次问题的排查归功于我的领导周庆民先生。如图6:因为自己用版本控制工具隔段时间就保存一次代码,通过各个版本的代码对比,将可能会产生错误的代码定位到下面几行。这是一个对串口2进行初始化的函数,函数中通过判断串口波特率标志位来给串口初始化为不同的波特率。由于串口波特率的标志位是在程序运行之处从存储器中拿的数据,而这个数据在参数初始化的时候又初始化成了零,所以在调用Rs485Init()初始化串口2的时候由于相应的标志位并不==2或者==3,所以程序并没有调用Uart2Init()去初始化串口2,于是在后面紧接着调用串口2收发数据的时候出现了问题,抛出了硬异常。

解决方法:将代码else{;}改为else{ Uart2Init(…);},这样无论串口初始化的标志位为多少,串口2总能得到初始化,不会在调用串口2收发数据的时候出现异常。

问题反思:写代码的时候考虑问题一定要周全,考虑当条件不满足是需要做怎样的处理。



图6
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: