工作中遇到过什么奇怪的问题或bug吗?最终解决了吗?欢迎点击阅读原文与帖子分享。
下面,跟着我一起看看大家在工作中遇到的bug和解决技巧吧!
kuailewangzi8:
话说,刚参加工作的那会,给公司领导演示新开发的产品,心情那个即激动又紧张啊,明明已经试好的产品就是没有反应,当时想咋回事,闹鬼了吗?一遍一遍的试啊,就是没反应,紧张的汗都出来了,
最后才发现原来是试验台上的电源开关忘记开了,蓝瘦,香菇。领导走的时候脸都绿了......(我当时是太鸡冻了,大家别笑我啊!
)
Sur:
其实说到BUG,做程序的大家基本都遇到过。
BUG其实没有那么可怕,可怕的是,没有一个机制或者说是规则来避免发生它。
BUG产生的原因,我不能说我都知道,不过我可以分享一些我自己遇到的:
1、对芯片或者是对相关编程语言不熟悉,比如,前段时间写的一个VBA程序,右击的时候增加自定义的菜单,实际出现了右击时出现啦多个自定义的菜单,因为自己没有加删除自定义菜单的功能。在这里的感想就是,在编程时,既然你定义了一个变量,也就是你创造啦一条生命,你要规定好它生存的地方,和使用寿命,不能让它肆意忘形,因为你不可能只创造出一条生命,你是一个造物主,你需要对面创造的生命们负责,至少对同一类生命是平等的。那么对于一个芯片来讲,它的资源毕竟是有限的,那么你创造的生命就不能无限使用这些资源,所以你需要规定好他们生存的周期。
2、对不熟悉的东西,或者没有准确资料的时候,凭着自己的经验去揣测一些自己认为的东西,结果自己越想越有道理,越想越能说服自己,这个时候就是你迈向深渊的最后一脚。例子嘛,举一个自己亲身的经历,那次拿到一个开发板,没有原理图(很尴尬),需要自己去确认一个开关的高电平有效还是低电平有效,结果我就确认反了,整个结果和要求就是反的。也是工作之后的第一个正式的BUG吧。当时自己很确信自己是对的,觉得自己很有道理 。哎,生活就是这样来教育人的。做项目的时候,务必要拿到准确的资料,充分理解之后去确认你的编程,千万不要自己去揣测,即便资料不全,自己也要向资料提供者去确认你的揣测,因为他比你权威,其实事实不是这样,现实中往往出现这种BUG是要担责任的,所以做一个程序员,你要明确自己的定位,有锅让别人去背,咱程序员不被锅。
3、没有一颗对编程敬畏的心,使用了一个变量,却不明确它的限值,不是忘记啦,就是想让它成为炸弹,见过千千万万的限值的问题,有TFT屏幕大小,图片大小,文字大小,电机的旋转的角度,因为这时候限值都被狗吃了,吃了
。以前淘宝有个抢红包的游戏,就和《Flappy Bird》一样,不过阿里的程序员显然忘记了限值这个东西,那个鸟可以一直往上飞,都掉不下来的那种。大家编程时千万记住。
4、硬件也碰过,至今唯一比较值得肯定的就是一手还行的烙铁技术吧,只要不能BGA之类的封装难为我,基本其他还是可以搞定的,对了,还有一个惧怕的就是一种很密的排线接口,每次都会焊坏掉。对于硬件的BUG也有很多方面,不过面对这些异常时,我也有一套自己检查的办法,从电源查起,一块板子你如果排除啦软件问题,那么你就可以开始电源检查大法,芯片坏掉的其实很低,仔细去检查你板子上的电源电路,每个电源的去看。然后针对功能的检查,比如输入信号的问题等等。很多问题都是细节上的问题,很多问题都是角落里的问题,很多问题你遇到多了,你就是大神。
对于变量,记得明确它的类型,使用场所,特殊状态下的值,上下限值
对于软件,一个好的构架,也是一个不错的开始
对于编程,请对它保持敬畏
对于BUG,请不要害怕它,遇到多了或者看多了,你就是大神
当然我觉得有一种BUG不应该算作我们程序员的BUG,就是芯片用户手册错误引起的BUG
nwcheroes:
周五才解决的一个bug,嵌入式linux系统上,开发的一个.so供其他模块使用。系统开机的时候极小概率出现core dump。gdb调试发现dump在std::_Rb_tree::_M_erase,这个是C++一个类里的map成员,这个类就叫类A吧。
最初查找的时候,代码一行行看,也找同事帮忙看,都没找出问题。
在复现bug的时候发现使用这个库的模块因为收到了两次电源关闭状态变更的消息(据同事说这里是为了处理某个bug添加的),导致调用了两次类A的析构函数,这就导致系统去释放了两次map成员,第一次释放map中有数据没问题,但第二次释放因为map已经是空的了,所以系统再调_M_erase就会导致core dump。
最后解决的方法是在析构函数里加入手动清空map的代码,map.clear(),这个函数即使map是空的也可以使用。
所以搞这种linux系统开发各个模块间的耦合度不能太高啊,单独调试一个模块没有问题,一旦联调就各种莫名其妙的bug
qwerghf:
同样在调试207程序的过程中,用IAR给板子下载程序,发现最初的四块板子可以运行,从库房拿的新的板子烧写进入,发现运行不了,由于这次电路不是我设计,我怀疑是电路的问题,是不是有什么不同的地方,检查了几次觉得并没有什么不同,问了硬件工程师有什么不同,硬件工程师说板子都是一批的,不会不同,所以用最出写好的固件,用jflash烧写进去,发现新的板子可以正常工作,然后就想起来原因,原来是我忘记了boot烧写,由于我们的程序是boot+app,我直接用app的工程调试可以正常从app启动,如果拔下仿真器,就会因为没有boot,无法跳转到app,所以大家在以后调试boot+app工程的时候不要忘了烧写boot。最好调试后把boot+app合板烧写进入,避免这个bug。
飞翔荷兰人号:
以前用430做一个串口通信7,用上位机调试怎么都调不通,但是奇怪的是,插上仿真器就正常了,仔细捋了一遍,发现插上仿真器以后整个系统唯一的不同就是共地了,事实证明确实是430板子连电脑那边的杜邦线有问题,换根线就正常了。
Bingqi23:
说一下曾经遇到过的一个车载导航的S级别Bug,当时查了好多天才解决的。
Bug现象:随机操作机器reset。
拿到这个Bug时,是一脸懵逼,情报也太少了,无从开查,只能再现。经过了2个多周的日夜再现,最终竟然找到了100%的再现操作,天知道我是怎么碰大运发现的。
再现操作:机器供电后,Power Off/On操作反复100次,机器就会Reset。
知道了再现操作,剩下的就好办了。首先将看门狗生效后打上断点,再现,发现Reset是由于看门狗生效,被咬死的。那就是喂狗失败,可能程序中有死循环。
一般思路是将wdt禁用,然后再现。当问题发生时,就能找到其所在的死循环处。但是如上操作后,当再现时确发现系统调度正常,在各个Module的Task里打断点,发现都可以跑到,并没有在某处死循环处。
于是改变了一下调查方向,从wdt入手,查找什么原因导致了喂狗失败。
由于芯片自身的硬件wdt的触发事件都比较短,配置成最长时间也才1.4ms左右,对软件来说不够用。所以对硬wdt进行了一层软件封装,定周期给watchdog Task发Event。当收到Event时,喂软狗。
问题再现时,发现Event没有收到,通过断点调试,发现所有的中Event都无法进行收发了。经过一通Debug,找到了根源,是由于此时的Event队列已满了,事件无法继续入队了。此时打开消息队列的内存处发现,里面都被同一个事件塞满了。
为什么这个事件没有人去Receive它呢?查找它的receiver,发现了问题。原来是一个已经不用的task,当初代码注释没有注释干净。而这个事件是在每次poweron操作的时候进入event队列中的。
到此,整个事情的前因后果都清楚了。
每次powerOn操作的时候,会有一个无用的event入队。当进行了100次的PowerOn操作后,队列中就残存了100个这个无用事件。而整个消息队列的Size也是100,于是乎,消息队列被塞满了。此后的所有event都发送失败了。于是乎,喂软狗的那个事件发送失败了,于是乎,软狗喂不了了,于是乎,狗咬死片子,Reset了。
整个调查加修改bug过程持续了2个多周,其中的大部分时间都用在了再现Bug上。真正调Code改Code的时间,实际上也就是只用了一两天时间。其实,我觉得,如果有一个能百分百再现的操作手顺,这对调试Bug是一个十分重要且有用的前提。
ts1607:
服务器组遇到个问题:
服务是从Kafka里面取出数据,然后把offset存储到ssdb中,每个topic和partition都对应ssdb中不同的key,服务启动之后,每次kafka数据更新我们这边收到消息,然后存储之后就发现ssdb的值偶尔是-2。
这就奇怪了,最开始我们是在代码中打印存储的日志,发现没什么问题,后来去查看ssdb的日志,才发现里面每次set的时候都会对同一个key存储2次,一次正确的值,一次是-2,当-2先存储的时候那么再次读取的值就是正确的,否则就是错误的。
最开始大家以为是代码的事,所有人一起看也没发现什么问题,然后我们怀疑是ssdb的服务器有问题,把ssdb杀掉,然后重新编译一个也是有问题,最后大家想可能是erlang的ssdb driver的问题,结果在driver中也加了打印信息,发现也就发送了一条ssdb set命令,这时候我就怀疑有可能还有个node也链接kafka然后也往这个ssdb中存取数据,那么测试就好办了,把我们的节点停掉了,然后再往kafka发消息,结果ssdb果真又出现了个-2。
把这个节点停掉,启动正确的节点,果真一切正常了。
fyaocn:
说一个曾经非常低级的错误。电源问题。
测试一个新的电路板,用5V供电,用linux系统。就随手用了1个手边的手机充电器,开始效果很好,启动,然后就正常初始化,各个模块逐个加载,但是每当运行到一半时,就突然重启,不断循环。
正常情况下,就逐个排查问题,用万用表查电压都正常,然后就怀疑是否系统有bug,排查模块加载。当然,那个过程是很长的,但是没有任何结果。。。没找到问题。
后来,没有办法,换了一个电源,就一切OK了。
结论:这个手机充电器是山寨版,用一会儿供电不足,电压降低,板子就重启,给手机充电没有问题,因为手机也不需要连续供电。而且看起来也很正品。这个坑,遇到不明白的问题,电源有问题的可能性最大,以后知道了。
xudeng22:
说说以前做的一个产品吧。
一款量产的便携式手持产品,开机工作正常,等待检测不到传感器时,自动关机(省电设计),此时正常状态。反复开关机正常。
但是,BUG出现了,关机后,1,2秒之类立即开机,不能启动,不能启动,不能启动。
软件有BUG,查了又查,没有BUG.
只有硬件了,对了,从电源入手,原来是用了国产某款LDO,关机时,电压下降为0V的过程太慢了,导致无法再次启动,需要3~4秒才能下降到0V。果断换了LDO,没问题了。
最后,希望国产IC越做越好。
迈尔风随:
今天就发现一个,使用keil V5对新唐的M051系列单片机进行在线调试程序,进入调试界面时都一切正常,一点击“全速运行”按钮,就弹出调试命令错误的提示:
检查了一下,能正常下载程序和运行,那说明连接线连接没有问题,然后就把所有相关的设置项都检查一遍都是和以前的一样没有改动,之前的工程就能正常调试,而新的却不能。接下来重启电脑、重新打开keil、工程目录设置为全英文都没有用,还是一样的问题,没有招了只好去问度娘,看到有说是因为打开了芯片内部看门狗的事情,我的程序里确实是使用了内部看门狗,赶紧把看门狗的代码注释掉,编译、进调试,点运行,一切正常,问题解决,原来真是看门狗引起的问题,但是为什么会这样还不太清楚,也许是仿真用的时钟太快,导致看门狗复位的时间缩短才这样?如果有大神知道原因的话,希望不吝赐教。
y909334873:
说说最近遇到的各种问题,首先是sd卡fatfs文件系统的时候,spi通信很正常,就是创建文件后不能直接往文件里写数据,或者只能更改已经存在的文件里面的数据。这个之后换了fatfs版本之后修复了这个问题,但是比较两个文件没有明显的不同,到现在也没搞清楚什么问题,等这段时间忙完了要好好看看。另外就是之前有发过的窗口看门狗的问题的时候在中断函数里清完中断标志后,需要等待一段时间,不然一直复位。还有就是自己定义了一个char buf[]="000";char buf2[]="111"当我在后面的操作粗心的给它一个比如buf=“0000”;然后我在进行一些需要判定"