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 )
限量版产业观察、行业动态、技术大餐每日推荐
享受快时代的精品慢阅读
 

 

继续阅读
赛普拉斯PSoC6正式接入阿里云Link TEE加强物联网应用的安全设计

全球领先的嵌入式解决方案供应商赛普拉斯半导体公司(Cypress Semiconductor Corp.)(纳斯达克代码:CY)日前宣布,旗下物联网计算和无线解决方案PSoC 6 MCU芯片进一步加强了对阿里云平台的安全接入的支持,目前已支持阿里云面向IoT领域的嵌入式操作系统AliOS Things以及阿里云Link TEE。

要做独立MCU生态,你看好灵动微电子吗?

MCU微控制单元又叫单片微型计算机或者单片机,是进行嵌入式开发的核心部件。小到智能手环、大到智能手机,都可以统称为是嵌入式开发系统,而物联网节点就是一种嵌入式系统。

MCU巨头的物联网之争,MCU如何AI化?

近几年,存储芯片价格的持续上涨推动了半导体市场的增长,这也让三星电子取代英特尔成为半导体市场的霸主。不过,随着2018年下半年存储芯片价格的下跌,半导体市场的寒意也在增加。正是由于市场的这种转变,业界尤为关注负面消息,非常典型的就是裁员以及工厂停工。

2030年的汽车超级ECU架构
2030年的汽车超级ECU架构

在整理汽车电子发展的时候,看到了一个欧盟赞助的项目是有关于高运算能力的计算平台的发展,这个项目的名称是《European Processor Initiative》它是欧洲发展高运算能力计算平台,面向未来的AI和5G社会的一个研究项目。

【技术分享】三种办法教你如何破解加密MCU

MCU的安全等级正在逐步提升,一些公司甚至推出了安全主控,这是很好的现象,说明大家越来越重视嵌入式领域的信息安全和程序安全了。但对于很多特殊行业,比如消费类电子产品、低成本的通讯模块、电源控制模块等等,迫于成本压力以及更新换代速度问题,都无法使用更安全的主控MCU,有很大一部分产品甚至还在使用51单片机。

更多资讯
工程师为室内导航设计出“看不见”的二维码
工程师为室内导航设计出“看不见”的二维码

用于机器人室内导航的隐形二维码。 使用UV或IR照明可读的隐形标签。

英特尔收购Omnitek,只为进军FPGA市场?
英特尔收购Omnitek,只为进军FPGA市场?

4月18日消息,英特尔近日宣布收购了家领先的优化视频和视觉 FPGA IP解决方案提供商 Omnitek。据了解,Omnitek的技术在 FPGA 上实现了定制的高性能视觉和人工智能 (AI) 推理功能,能够满足各个终端市场的客户需求。

音乐也开源,工程师制作电子木管乐器

在当今的数字乐器市场中,MIDI木管乐器控制器的选择非常有限。 该项目旨在将DIY开源版本带到普通制造商可以创建和播放的版块中

芯科科技推出了满足最新一代PCIe 5.0规范的完整时钟解决方案

- Silicon Labs(亦称“芯科科技”,NASDAQ:SLAB)日前推出了满足最新一代PCI Express®(PCIe®)5.0规范的完整时钟解决方案组合,能够提供同类最佳的抖动性能,且具有显著的设计余量。

在软件定义的时代,风河公司如何推动创新的步伐?
在软件定义的时代,风河公司如何推动创新的步伐?

风河公司在自治和互联的新要求和新时代下,通过新产品和新技术继续引领潮流,在软件定义的时代推动着创新的步伐,帮助一代代世界技术领军者不断适应安全设备的最严苛要求。

Moore8直播课堂
开发板测评
技术讨论
电路方案

1970-01-01 08:00:00