分享一些网友工作中遇到的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”;然后我在进行一些需要判定"\0"的函数时,就会导致打印出的数据是“0000111”这样的情况,还有好多,虽说有改不完的bug,但是每一个bug都有它存在的原因。找bug的过程是痛苦的

,解决bug的时候是

suoma

arduino和enc28j60网络通信问题
下了最新的ethercard库 貌似CS接8或10 都ping 不通 是同一网段 接线是 INT - 2 , SO - 12 , SCK - 13 , RES - RES , SI - 11 , CS - 10 ,VCC - 3.3V ,GND - GND 板是UNO  , 代码是用本帖的代码
提醒大家一点,很容易犯,而且很隐蔽的一个错误:mac地址第一字节必须是偶数。
// PIN Connections (Using Arduino UNO):
//   VCC -   3.3V
//   GND -    GND
//   RESET -  RESET;
//   SCK - Pin 13
//   SO  - Pin 12
//   SI  - Pin 11
//   CS  - Pin  10

青蛙叫

Server Tomcat v7.0 Server at localhost failed to start.
遇到以上问题一般是由于web项目中配置出现问题,可能是使用了@WebServlet配置,同时有使用了Web.xml文件配置,导致工程和服务器开启失败。
Target runtime com.genuitec.runtime.generic
解决方案,在工程目录下的settings文件夹中,“org.eclipse.wst.common.project.facet.core.xml”这个文件也需要修改下打开该文件,会发现<runtime name="com.genuitec.runtime.generic.jee60" />,把这句话去掉就可以了,回到IDE工具中刷新一下工程就解决了。

phwj2006

超级奇葩的bug。

使用cc430无线通信,调试过程中能进入接收中断,但是收到数据总是ff,f3,两个数字循环。无论发送什么数据,接收端收到的永远是这两个字节。

各种找问题,发送确认发送出来了,接收确认进入接收中断。

查找问题,各种排除法,确认寄存器没有问题,确认流程没有问题,。就是找不到原因。

后来直接用串口打印竟然是对的。

最后发现引起这个问题的原因竟然是编译器BUG,更改高版本的编译器解决问题……

miaozhuang156

就在昨天,我的手机努比亚小牛z9mini,发生一件诡异故障,手机能打电话,发短信,但就是不能上网

,无论是格式化,恢复出厂设置,刷机。都没软用,从上午一直搞到下午都没用,我一想,是不是手机硬件坏了

主要当地还没售后,这一下不麻烦了吗,于是乎想起了客服,一问才知,原来z9mini刷机,升级操作失误等,就容易把MBN文件搞丢失,按照客服指示,按手机*#626#查看MBN文件,整个文件界面为空,此时心里不禁暗喜,还好没硬伤,马上让客服把教程发过了,就开始弄,后来由于电脑上缺少驱动,费了好大劲才安装好,按教程一步一步来的,没想到还真弄好了,后来一回想,可能是前几天在单位升级手机系统,中途网络断了一下,把MBN文件弄没了的缘故,想想真是坑啊。。。。。最后希望论坛朋友们有用z9mini手机的,如果出现类是我这种问题可以按以下教程刷一下,但愿可以解决此类问题

wateras1

分享下今天遇到一个奇怪问题:今天测试有线网关代码时遇到一个很奇怪的问题,接收手机app端发送的json格式数据,STM32直接进入到了硬件异常中断了,后来发现是定义的栈太小了,将原来的2K改成了4K,一切正常了。
分析解释如下:
函数的局部变量,都是存放在"栈"里面,栈的英文是:STACK.STACK的大小,我们可以在stm32的启动文件里面设置,在startup_stm32f10x_hd.s里面,开头就有:

Stack_Size      EQU     0x00000800

表示栈大小是0X800,也就是2048字节.这样,CPU处理任务的时候,函数局部变量做多可占用的大小就是:2048字节,注意:是所有在处理的函数,包括函数嵌套,递归,等等,都是从这个"栈"里面,来分配的.
所以,如果一个函数的局部变量过多,比如在函数里面定义一个u8 buf[512],这一下就占了1/4的栈大小了,再在其他函数里面来搞两下,程序崩溃是很容易的事情,这时候,一般你会进入到hardfault....
这是初学者非常容易犯的一个错误.切记不要在函数里面放N多局部变量,尤其有大数组的时候!

1055875333

最近在调试电视机案子时,遇到HDCP 2.2 KEY识别不到的问题,现象及解决方法如下:

【现象】
   EDID检查正常,但接4K2K60HZ信号黑屏,HDCP 2.2 KEY一直认不到,且打印I/tvos    ( 1089): [MStarSDK] mapi_video: HDCP2_LoadKey failed.

【解决办法】
   最后将hdcp2.ini里改了HDCP_RX_KEY_PATH=/data/hdcp2_key.bin
   hdcp2.ini其实就是在libhdcp.tar.gz里面。所以最后让MStar更新
   develop/extra/target/arm-gnueabi/libhdcp.tar.gz
   tee/Apps/install/HDCP/libhdcpTA.a
   替换上去即可重新编译Supernova即可。

ywlzh

bug?
底板 stm32f103vct6 时钟在初始化的时候选择是的外部时钟,也就是晶振,启振了,初始化成功,但时钟频率一时对一时不对,硬件仿真死活没有跳到异常里面去,开个硬件定时器,计算一秒灯闪一下,结果这个灯不按套路出牌,想怎么闪就怎么闪,CPU竟然还运行着,死活不进异常。
解决方法:换单片机

596937862

我是搞物联网嵌入式技术的,最近在搞关于Contiki的教材研究和编写工作,想要编写一本关于Contiki的教材并不容易,因为Contiki的代码顺序很乱,代码很混乱,找一个代码来源要翻阅好几座山,才能找到,各种引用,有时候真要崩溃了。有一次写一个Rime多跳协议怎么也编译不出来,试过各种办法,每次尝试的结果都不相同,代码改了无数遍始终找不到根源,最后才发现是调用底层代码的时候,名词少了一个y字母,我也是醉了。。。做程序员每天要被bug折磨死。

wugx

软件方面,我想说的是有时候bug就是一个字符的差别,短则找个几分钟,长则几天,呵呵,多亏现在的编译器越来越对程序员友好了
硬件方面,共地共源经常出问题,画pcb的时候眼睛不睁大点,一条和网格重合的线就没画,做出来的板子要被该的乱七八糟,这还是找到问题了的
。。。。。。总结一下,很多的郁闷bug都是自己的马虎大意造成的,这也没办法,几十年了,人毕竟都有局限性啊,阿Q一下。

murongyu

上个星期遇到的怪异事件:用FPGA做了一个波形发生器。开发板硬件是没什么问题的。FPGA代码,理论上也是没问题的,正弦信号。测试第一天。用示波器测量信号,发现DA输出的正弦信号抖动太大,打开余辉后,发现出现波形跳变的情况。测量板子上的晶振,时钟信号很稳定,没有抖动。这个时候,认为是代码的问题。可是代码从头到尾检查了几遍,仿真了几遍,理论推导了几遍,都没有发现bug。第一天就这么郁闷的过去了。第二天,继续测,却发现输出的正弦信号不抖了,很稳定。一切正常。这个现象太奇怪了。同一个板子,同一个FPGA,同一个信号,同一个示波器,同一个探头,同一个设置,却出现不一样的结果。第三天,第四天,又继续测了很多次,无法重现第一天的抖动现象。目前工作非常正常,没有出现问题。怪异的事情发生过,却不能重现了。也只能说,无法解释。

ienglgge

lpc的一个单片机,串口和can与外界通信。有时候,收到一些can数据,就重启。can 先收到数据,串口后收到数据,正常。串口先收到数据,can后收到数据,就出问题。折腾半天。串口和can之间,貌似有些影响。后来,注释掉printf函数,靠,竟然正常了。而且,只要程序中有printf,即使根本不执行,也有影响。编译可以通过,运行时,就有影响。整个工程中,都没有printf语句,就能正常工作。。

xueyongchao8805

这个小BUG说大不大,说小不小。说大是因为解决的不彻底,说小是因为解决用了小trick。过程是这样的,用单片机控制无线串口模块。如下图所示无线串口模块,控制器是MSP430FR5969单片机。

板子做好,直接插上无线串口。图中无线串口M0,M1引脚在我的应用中分别需要时高电平和低电平,对应我的单片机IO口输出高低电平控制。实际情况是,拿下无线串口,不插在板子上。用万用表量取对应IO口输出电压,均为低电平,高电平。注意,前方出现奇葩BUG

,当我把无线串口,插在板子上,再用万用表量取M0M1对应IO口输出电压,均发生改变(系统已经上电),都变成低电平,使我的无线串口无法工作在我需要的低功耗接收状态!!!

,拿下来电平正常,接上电平奇葩,导致我就非常奇葩。明明IO输出电平没问题,接上就有问题。我就有问题了!!真心不知道怎么解决。

后来,由于无限串口仅需要工作在固定模式,即M0M1低高状态,遂直接将两个引脚直连板子的VCC和GND,才可以解决!但是,问题的本质问题并没有找到。借此机会,广大朋友也可帮助看下!!

huaiqiao

不好意思,这个帖子今天晚上才有时间回复。讲一下,比较近的一个故事吧。
是这样的,之前我来这个公司前,他们做了一批板子(5pcs),这个板子用的就是stm32f405.(有ti的电机驱动芯片,can收发器TJA1050,电磁阀MOS管驱动器等等)
先说第一个问题:
问题描述:这批板子中,有3pcs,用着,用着,不知怎么滴,VCC3.3V对地短路。然后接着就是CPU发烫。这个问题我在这个测评帖中大概讲过。(http://bbs.eeworld.com.cn/thread-496434-1-1.html)。
但是其余2pcs没有出现过这个问题。那么最后分析来分析去,觉得是CPU的问题。于是将CPU解焊,发现短路现象消失。然后又重新焊接CPU,依然发现VCC3.3v对地短路(简直是现象重现啊)。于是,就分析在焊接过程中的一些细节。
我们在焊接的时候,用了焊锡膏。然后用的是某宝买的洗板水。
后面做了个实验,单独焊接CPU(一个CPU30多块钱,算是挺贵的了)。也是用到焊锡膏,洗板水。结果上电发现,CPU有个引脚有轻微的火花。所以我们就觉得,有可能是洗板水的问题(某宝的,不正宗,很正常)。还有可能是洗板水和焊锡膏作用(应该是化学反应吧)后,焊锡膏停留在cpu下面,焊锡膏高温后接触空气中的水分,使得板子上电后有轻微火花(很小的火花)。
解决办法:后来,本来之前layout的同事,将电机驱动芯片的走线,lay板的时候线宽有点小,所以觉得改版。正好撑着改版,换了个板厂,换了个人lay板,这个现象就再也没有发生过。
除此之外,某宝的洗板水也扔了,换了成工业了无水乙醇。

第二个问题:
问题描述:这个板子使用的JTA1050的can收发器。这个芯片的供电是5V的,设计者在设计的时候把它当成了3.3V的。所以can芯片不能正常工作。
解决的办法:
①、原来好的板子,使用TI的can收发器SN65HVD232D。这个芯片的引脚跟TJA1050完全兼容;所以不用飞线,不用割PCB的铜线。
②、在第一个问题的时候,因为要改版,所以乘机将这个can芯片换成了TI的can收发器SN65HVD232D。所以这个问题也解决了。

上期回顾:分享一些网友工作中遇到的bug和解决技巧(一)


(0)

相关推荐