Bug虐我千百遍,我待bug如初恋

2019-01-24 14:33:16 来源:EEFOCUS
标签:

文/山坡羊

 

语言做为人类交流的工具,会随着社会和时代的发展而被赋予新的内涵,正所谓“苟日新,日日新”是也。比如,“聪明绝顶”这个词儿,以前的意思大概是指太过于聪明,以至于“会当凌绝顶,一览众山小”,没有比他更聪明更拉风的了。但是现在,似乎更加合理的解释是“聪明人爱动脑筋,以至于脑瓜壳都秃了”,前段时间有个段子就是讲这个的,说是在北京中关村地铁站那里会上来一群“聪明绝顶”的人,那闪亮亮的头顶,洋溢着智慧的光芒。佛门有谓“无缘大慈,同体大悲”,无缘大慈是说没有缘由地对别人好,同体大悲是说将他人视为一体,以众生之苦为自己的痛苦而产生大悲心。看着图中这些熠熠生辉的脑瓜壳,别人能否升起同体大悲不好说,笔者做为一名程序员同类,倒是有了一种兔死狐悲的悲凉之感。

 

中医理论认为,“肾藏精,主生殖,其华在发”,如若肝肾两虚气血不足,全身的血液循环就疲软,无力将营养物质输送到人体直立的最高处“头顶”,头上毛囊得不到滋养,渐渐萎缩,就会引起脱发。脑力工作者“殚精竭虑”,耗费元气,容易伤及肾精,按照上述中医理论的逻辑链条,自然会得出脑力工作者容易脱发的结论。

 

 

中关村做为IT工作者密集集散地,脑力工作者-程序员比例最高,用脑过度->肾精亏虚->气血不足->脱发,正好可以完美解释中关村地铁站秃头比例异常。从笔者为数不长不短的程序员职业生涯来看,这种秃瓢遍野的情况和程序员日常工作中大为耗损元气的“找bug”密切相关。


Bug,众里寻他千百度
时光永远向前,再回首已是昨天。貌美红颜,经不住时间的摧残,春风吹红了花蕊,匆匆一瞬间,秋风就带走了似水流年。岁月无情,可以说,程序员的一生,都是在与bug相爱相杀、殊死作战的生涯中度过的。。。

 

前段时间写代码,遇到了一个极其诡异(是的,这就是程序员对bug的第一反应)的事情,欲知详情如何,先上一段代码,
uint8_t  data[100];
uint16_t cnt;
….

cnt++;


funA();
….

if(cnt >= 350){
funB();
cnt = 0;
}

简单解释一下吧:定义了一个16位整型变量cnt,它在一个函数中执行累加操作,累加到350时执行funB操作。

 

这段程序逻辑清晰,代码也再简单不过,本该万事大吉,阿弥陀佛,结果,运行起来,死活进不了funB,进一步追踪发现,cnt累加到255之后,再累加就变成0了。奇怪了,8位整型变量从255之后累加变成0还情有可原,16位整型变量怎么会变成0呢?

 

是地址对齐的问题?笔者想到,使用的是16位单片机,如果cnt地址是个奇数,是不是会出现255累加变成0的情况?我特意查询了一下cnt变量的分配地址是不是能被2整除,可以整除,没问题!

 

MCU对变量缓存的问题?给cnt变量加volatile类型,volatile uint16_t cnt,结果依然如此!!

 

是编译器优化问题?在cnt++操作前后加入NOP指令,还是解决不了!!!

 

那是啥子问题?!!!!

 

有人说,“世界上最遥远的距离,不是生与死的距离,不是天各一方,而是,我就站在你的面前,你却不知道我爱你”,我要说,“世界上最遥远的距离,不是设计与实现的距离,不是不会编程,而是,我就站在代码的面前,明明知道有bug,但就是找不到在哪里。”

 

人类的世界里刀光剑影、尔虞我诈,但是,计算机的世界中从来没有算计,都是童叟无欺。本着这种朴素的态度,我开始回光返照,不再从MCU、编译器这些外部因素上找借口似地查找问题,开始直面自己写的代码,一句句读,一个函数一个函数地分析,终于,苦心人,天不负,bug终于找到了,真主保佑,阿弥陀佛!

 

原来,在函数funA()中存在对数组成员data[i]的赋值操作,这里的i和cnt变量有一定的关联。本来,data[100]这个数组占用了100个字节,可访问的下标范围是[0,99],最大下标应该是99,即data[99],结果,在cnt为255时,由于上述的关联,恰好出现了i=100的情形,这时对data[100]有个赋值为0的操作。

 

根据编译器对变量地址空间线性连续分配的原则,由于
“uint8_t  data[100];
uint16_t cnt; ”
cnt变量地址应该位于data[99]后面,这里所谓的data[100](逻辑上并不存在data[100],但是在地址空间上存在)正好是cnt变量的高字节(cnt变量占2个字节:高字节和低字节),所以,cnt为255累加之后,结果是256,即高字节变成了1,低字节变成了0,因为data[100]=0的原因,cnt的高字节变成了0,导致cnt=0。(如果非程序员身份的读者没看懂也就算了,人生还有很多重要的事情,何必事事都弄得很清楚呢?如果是程序员却没有看懂,不好意思,请问你的编程是跟体育老师学的吗?)

 

本质上来说,这个bug的源头是data数组越界,越界导致临近地址空间上的变量发生了非预期的变化,原因出在data数组上,但是表现出来的现象却和data数组没有一点关系,所以才那么难找。好在,笔者一贯勤于自省,对bug也从不放弃,有时甚至达到废寝忘食的地步,才终于找到了它并将之绳之于法!


对bug的态度
对程序员的日常生活来说,没有bug,那就是“无惊无险,又是一天。”出现bug,那就是“翻江倒海,忙活一天。”虽然好逸恶劳是人之天性,但是,不喜欢bug的程序员就不是一个好的程序员,有首歌怎么唱来着,“没有bug的日子很无聊,没有bug的锻炼,水平也很难提高。”所以,看到网上有人写到程序员遇到bug后,掩耳盗铃硬说bug不存在的反应,笔者只能苦笑一番:程序员对于bug那种既爱且恨、欲拒还迎的那份情感,岂是外人所能理解?!我们这些不甘沉沦的程序猿、码农和码畜们,对于bug,爱得有多么轰轰烈烈,恨得就有多么咬牙切齿!bug是我们的钢,bug是我们的粮,一天不见就想得慌。

 

“何以解忧,唯有杜康”,喝点小酒,微醺一下,妙不可言。Bug也是程序员的小酒,捉小bug是一件非常惬意的事情,顺风顺水,手到擒来,颇能给人一种“世界之大,任我逍遥”的成就感,这种自鸣得意是一种精神上的鸦片,解决小bug的忘我和喜悦会使人忘记尘世的烦恼,那种洋溢在内心的淡淡喜悦可以延年益寿,百病可除。

 

捉小bug虽然能够强身健体,愉悦心情,可是,捉大bug就需要伤筋动骨,颇费脑筋了。因为,小bug的原因和结果往往都体现在相同的位置上,因果反推,就能从bug现象推导出bug的原因。但是,大bug一般来说其最终的表现形式和最初引入bug的位置没有直接的因果关系,这里有一个很隐秘的故障-失效的传导链,在故障现象和故障原因之间很难直接反推,这时,就需要平心静气,以废寝忘食的态度和耐心仔细查验代码,推导程序运行的过程,这个过程最考验程序员的功力和耐心了,当然,这个过程是没有喜悦可言的,也极其耗费脑力,进而耗费精气,再进而“聪明绝顶”。不过,尽管过程是曲折的,但是前途是光明的,一旦找出来大bug,亲手把它灭掉,那种透彻心扉的喜悦,那种守得月明云开的通透感,有时都能让人感动地掉下泪来,这,就是对艰辛劳动的最好回报!!

 

对待bug,我们要像丘吉尔发表的那篇著名演说那样:“我们将战斗到底。我们将在开发环境中作战,我们将在代码的海洋中作战,我们将以越来越大的信心和越来越强的力量在bug作战,我们将不惜一切代价保卫系统,我们将在调试中作战,我们将在仿真系统中作战,我们将在测试环境中作战。We will never surrender!!”掉头发就掉头发吧,秃顶就秃顶吧,衣带渐宽终不悔,为伊消得人憔悴,不过也省洗发水了不是?


与非网原创内容,未经允许,不得转载!

 

 
关注与非网微信 ( ee-focus )
限量版产业观察、行业动态、技术大餐每日推荐
享受快时代的精品慢阅读
 

 

继续阅读
做好“当家”MCU产品,ST在持续创新的道路上“稳操胜券”

MCU是电子产品的控制中心,已经广泛应用到很多消费电子和工业电子产品中。随着物联网和新能源汽车的高速发展,未来MCU的市场呈现爆炸性增长态势。IC Insights预测,近五年MCU会以7.2%的复合年成长率(CAGR)增长,到2020年销售额会达到约239亿美元,单位出货量将达到约438亿台。这对全球的MCU厂商来说都是一个好兆头,但是

MCU还有很多创新点,打价格战不是最好的取胜之道

MCU产品的应用非常广泛,大到汽车、飞机,小到手环、儿童玩具,都需要MCU控制,因此MCU产品的市场销量一直呈上升趋势。IC Insights预测,到2020年销售额会达到约239亿美元,单位出货量将达到约438亿台。在出货量居高不下,而单价在走低的大趋势下,芯片厂商在产品研发上有哪些应对策略?如何保持公司的稳定增长,从而避免陷入价格战?

Renesas Synergy™ Platform新增低功耗S5D3 MCU产品组

全球领先的半导体解决方案供应商瑞萨电子株式会社 ( TSE : 6723 ) 今日宣布,扩展高度集成的 Renesas Synergy™ S5系列微控制器 ( MCU ),推出入门级 S5D3 MCU 产品组。

要打赢MCU市场的争夺战,先做好产品差异化

MCU在消费电子、汽车电子和工业控制等领域应用广泛,未来随着物联网、自动驾驶等创新应用的快速发展,市场对MCU的需求将进一步增长。据IC Insights预测,到2020年,全球MCU行业市场规模将突破200亿美元,中国的市场规模或将突破500亿元,发展潜力巨大。为了满足应用需求,MCU产品也从8位演进到16位、32位,但是价格却在下降,

提供新的人机接口实现方式以减少大量需求资源
提供新的人机接口实现方式以减少大量需求资源

大约十年前由于iPhone的推出使我们的日常生活产生了重大改变,利用触控来操作手机的方式扮演了至关重要的角色让我们与科技有了实时的互动。

更多资讯
打破价格垄断,工程师自制动作捕捉系统

今天为大家介绍一个自制的动作捕捉系统Chordata,这是一个你可以自己构建的动作捕捉系统。 我们的目标是通过开放硬件方法将动作捕捉世界带入DIY技术领域

面向IQD新缩小尺寸纪律OCXO的嵌入式显示发布

Embedded Show launch for IQD’s New Reduced size Disciplined OCXO

12自由度out了,工程师自制22自由度机器人
12自由度out了,工程师自制22自由度机器人

机器人机构能够独立运动的关节数目,称为机器人机构的运动自由度,简称自由度(Degree of Freedom),由DOF简写表示。 机器人轴的数量决定了其自由度。是不是自由度越多越好呢?自由度越多就越接近人手的动作机能,通用性就越好;但是自由度越多,结构越复杂,对机器人的整体要求就越高,这是机器人设计中的一个矛盾。

80年历史看三星半导体超越英特尔绝非偶然?(下篇)
80年历史看三星半导体超越英特尔绝非偶然?(下篇)

在上篇中我们回顾了三星半导体的诞生以及它对手机和存储芯片的倾力投入和一段艰苦岁月。本文我们继续看这家公司怎么成长为芯片产业的一哥。

IBM如何从一个落伍者重回数字计算第一梯队
IBM如何从一个落伍者重回数字计算第一梯队

IBM在上世纪80年代的信息革命中,不情愿地成为了落伍者——虽然IBM最早推出了个人电脑,但是由于IBM的保守性,最终没能成为个人电脑之王。反而是微软和Intel借助个人电脑市场逐渐做大,并逐步侵蚀IBM的传统市场。IBM随即出现了严重的亏损,并打破了IBM从不裁员的神话。这段时期,是IBM历史上最艰难的时期。当时有人甚至质疑IBM公司是

电路方案