专栏首页TencentOS-tiny【编译器玄学研究报告】第二期——break

【编译器玄学研究报告】第二期——break

【说在前面的话】

编译器玄学报告第一期出来后,并没有任何人理睬我在文章一开头留下的问题,相反大部分人都是来围观“闰年更新”的

……更有甚者感慨:我娃都出生了,这个公众号终于更新了。真的非常非常抱歉,感觉辜负了很多人的期待;同时也非常非常的感谢,感谢你们的耐心和信任——为了纪念这一时刻,我准备就大家非常信赖和依恋的armcc(Arm Compiler 5)爆个黑料。让我们来围观一个如假包换的编译器bug。


【正文】

Arm Compiler 5,也就是大家熟悉的armcc,距离官方2017年最后一次更新已经过去3年多了。实际上官方早在2016年发布Arm Compiler 5.06u3的时候就已经通过各种渠道对外界喊话——“我要是再更新armcc,我就卖了我自己”,结果2017年,5.06u6不期而至,孙正义爸爸的钱还是“真香”的——这里也许有些许戏虐的成分在里面,但armcc接近软件生命周期的终点是不争的事实:

  • armcc 真的太老了!也许用户用起来感觉还挺趁手,但实际上已经是“屎山”一座了;

今天,我们就给大家展示一个Arm Compiler 5.06u6 “最终绝对不改版6” 中一个惊为天人的BUG。

1、准备好一个新鲜的 Arm Compiler 5.06u6。如果不确定自己的armcc是不是这一版本,可以打开MDK的help->About,如果你是日常的armcc玩家,应该可以看到类似如下的信息(是的,就是这个 V5.06 update 6

2、随便建立一个可以编译和调试的例子工程,并将优化等级设置为 -Otime -O3。具体方法如图所示:

3、插入以下的测试代码

#include <stdio.h>

void break_tesk(uint_fast8_t chValue)
{
    printf("entering switch...\r\n");
    switch (chValue >> 4) {
        case 0: 
            printf("do something...");
            break;
        case 1: 
            printf("do something...");
            break;
        case 2:
            do {
                printf("\tInput is 0x%02x", chValue);
                if ((chValue & 0x0F) < 7) {
                    break;
                }
                printf("You will not see this");
            } while(0);
            printf("\tYou should see this ");
            break;
        default:
            printf("it is a default");
            break;
    }
    printf("\r\nleave switch...\r\n ");
}

4、在超级循环中调用该函数,并传入参数0x22,例如:

void main(void)
{
    ...
    break_test(0x22);
    ...
}

5、编译并运行,观察输出:

分析代码不难发现,针对输入0x22,我们会从do{}while(0); 结构中跳出,并继续执行后续的代码,也就是打印“\tYou should see this ”,因此一个可能的输出结果是:

entering switch...
        Input is 0x22   You should see this
leave switch...

然而,我们实际观测到的是:

6、修改优化等级为 -O3 -Osize(如图所示,只要去掉 Optimize for time前面的勾选就行了),编译并运行,观察输出:

可以发现,代码中 do{}while() 结构内部的break被错误的当作了switch的break,从而跳过了 do{}while() 结构后面的代码。通过修改优化等级到-O3 -Osize或者是-O2 -Otime都可以避开这一问题。那么,这一问题是否严重呢?我觉得我要手动@一下所有使用protoThread和所有使用switch状态机的童鞋们,就问你们慌不慌

【玄学说法】“状态机好像容易跑飞……我也不知道是怎么回事,代码逻辑没问题啊?”;“高优先级下生成的代码不可靠!”;“switch里面的break和for以及do while的break究竟怎么用?我好方”;“我遇到一个bug,你来看看”,“我什么都没改啊,换个优化等级就对了……”,

【实际情况】编译器bug没的洗……但是bug就是bug,不要怀疑人生,不要怀疑自己所学的语法,发现bug有条件的话请及时报告。


【后记】

其实按道理说,这种bug应该非常明显,不至于被留到最后一个版本,仔细想想,至少有以下几种可能:

  • 这是 Arm Compiler 5.06u6 从 5.06u5 升级过程中引入的——正可谓拔出萝卜带出泥。可惜实际情况并不是这样的。有兴趣的朋友们可以去测试下老版本;
  • 大部分用户对C语法掌握情况不佳,基本处于模棱两可的状况;遇到类似情况不会用一个严谨的态度首先去确认正确的语法及行为;在坚持正确语法的情况下分析问题,从而判断出这是一个编译器错误;
  • 大部分用户不敢用最高的-O3 -Otime优化;
  • 大部分开最高优化的用户关心的主要是代码尺寸,从而恰好避开了这个问题;
  • 大部分用户没空去纠结这一问题;
  • 大部分用户遇到这类问题后,默默的选了-O0……
  • 大部分用户相信玄学……
  • 少部分牛人发现问题后懒得报告……

“大人,时代变了”

最后,欢迎大家尽早投入到Arm Compiler 6、IAR、GCC的怀抱……

本文分享自微信公众号 - Mculover666(Mculover666)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • MSP430F5529时钟系统深究

    时钟系统是一个数字器件的命脉,对于普通的51单片机来说,它的时钟来源只有外部晶振,然后每12个振荡周期完成一个基本操作,所以也叫做12T单片机,但对于...

    Mculover666
  • PYNQ上手笔记 | ③PS端+PL端点灯

    上一节中分别独立实验了Zynq的PS端和PL端,并初步实验了PS端先硬件再软件的开发流程和IP核设计的设计方法。第一节中提及到:Zynq是以PS端的ARM处理器...

    Mculover666
  • 好玩!C语言打印彩色字符,还能闪烁!

    最近在研究日志打印组件easylogger,玩转各种彩色日志打印不亦乐乎,好奇心越来越重,遂深入研究,发现了一个非常神奇的东西:ANSI escape code...

    Mculover666
  • PowerShell渗透–Empire

    Empire是一款针对Windows平台的,使用PowerShell脚本作为攻击载荷的渗透攻击框架代码具有从stager生成,提权到渗透维持的一系列功能,无需p...

    糖果
  • 如何防御“神器”Mimikatz窃取系统密码?

    Mimikatz是一款能够从Windows中获取内存,并且获取明文密码和NTLM哈希值的神器,本文将介绍如何防御这款软件获取密码。 Mimikatz介绍 M...

    FB客服
  • 知道数据的分布有什么用

    这是我最近在想也没确切的想出来的问题。那我来看看从应用层面来说,看看哪里会用到数据分布吧~

    是可爱的赵赵晗
  • 《JavaScript 模式》读书笔记(8)— DOM和浏览器模式2

    可能会注意到有时候浏览器会提示某个脚本已经运行了很长时间,是否应该停止该脚本。实际上无论要处理多么复杂的任务,都不希望应用程序发生上述事情。而且,如果该脚本的工...

    zaking
  • 不到 3 天截稿!NeurIPS 2020 新要求提交的“影响陈述”还不会写怎么办?

    今年 2 月份,NeurIPS 组委会发布了NeurIPS 2020 在提交和评审机制上做出的一些重大更改,其中一项便是要求作者在投稿论文中单独拟一个“影响陈述...

    AI科技评论
  • 地理信息地图标记KML与KMZ的区别

    KML (keyhole markup language)是以XML语言为基础开发的一种文件格式,用来描述和存储地理信息数据(点、线、面、图片等),是纯粹的xm...

    学到老
  • 地理信息地图标记KML与KMZ的区别

    地理信息地图标记KML与KMZ的区别 KML (keyhole markup language)是以XML语言为基础开发的一种文件格式,用来描述和存储地理信息数...

    学到老

扫码关注云+社区

领取腾讯云代金券