section auto remove 引发的问题

        最近新开始的项目遇到一个小问题,记录一下。

        背景是这样的,我们之前做过一款SSD,有多种容量。以前开发这款产品的时候,我们采用编译期配置的方式,在开始编译每种容量的fw之前,需要先跑一个配置脚本将config.c文件中的#define都修改成对应容量的config。所以,假如现在有7种容量的SSD,我们需要编译7次,生成7个不同的bin file。这样既浪费编译时间,也不利于客户后续upgrade。现在,我们需要base在原项目的基础上,用同款SOC搭配新的nand flash开发新款SSD。在此背景之下,公司决定采用运行期读取配置的方式,这样只需要编译一份fw即可(虽然会牺牲一部分runtime的性能,还需要额外的动态空间分配,不过不在讨论范围之内)。

        因为比较简单,新任务被直接分配到刚毕业的童鞋手中。这个同学也很快完成了初步的代码,兴高采烈地上电启动,但是很不幸,SOC上电跑了还没有半秒钟就挂掉了。从uart上看,SOC上电之后也就只打印了寥寥几句log。这位同学一开始还觉得没什么太大不了,既然卡住了,那就再加log呗,代码我不熟悉,二分法也总能找出来吧!于是继续加更多的log,可是问题逐渐变得有点儿离谱了,因为他发现,每次上电卡住的位置都是不一样的,有时候甚至只是移动了一句打印,上电卡住的地方就会差很远了。这个同学经验不足无法解决,问题拖了大约有一周的时间。在过年前几天我刚好闲下来了,于是就帮忙看了一下这个问题。

        从他反映的上电现象来看,这个问题感觉很像是cpu跑死了。跑死了是什么意思呢?32位arm架构的内核有7种工作模式,SSD fw相对简单,不会使用到这么多工作模式,一般只需要两种就可以了,比如sys mode + irq mode ,而其他模式下的代码在基于SOC厂商sdk的基础上一般不会再做改动。比如当cpu fetch到了不合法的指令,就会进und mode,这时cpu就会切换到该模式下的堆栈并且跳转到对应的handler。这个旧项目有个特别坑爹的地方就是,它除了irq mode(正常跑使用sys mode),其他异常模式下的代码都是一个简单的死循环,所以即便发生了exception也无从得知。因此,要做的第一件事情就是先为其他几种模式加上合适的handler,至少需要在里面保存cpu register的值以及sys mode下的sp、lr等以便debug。

        我们在handler里加了register dump以及stack dump的代码。不出所料,上电之后马上就进入了und mode的exception handler,而且stack dump也非常有特点,sys mode下sp指针附近的堆栈都被填充成了0xB0B0B0B0,甚至好几个register连带lr都是0xB0B0B0B0,这显然是不合理的。而且,我们这款SOC是双核的,两个cpu都进入了exception。不过这下问题也还是好办多了,在项目代码中搜索“0xB0B0B0B0”,它出现在以下代码片段中。

       这里看起来应该是将cpu1 svc mode下的stack全部init成0xB0B0B0B0,方便之后检查stack的使用量。根据之前的stack dump,这个地方很有可能发生了问题,导致了越界的初始化。查看了一下链接之后生成的map文件,发现Image$$SVC_Stack_1$$ZI$$Length这个变量竟然变成0了。我们现在来看一下initstack这段汇编在Image$$SVC_Stack_1$$ZI$$Length为0的时候是如何导致越界的。

        这下答案应该相当明显了,initstack这个过程会先递减r4,再将r4与0做比较,假如r4是0,那么递减一次之后r4会溢出,最终结果就是导致stack的初始化越界了。这里的svc stack是cpu1的stack,但是由于溢出,也把cpu0位于dtcm上的所有stack都盖住了,所以两个cpu都进入了exception mode。至于为何Image$$SVC_Stack_1$$ZI$$Length会变成0,后来对比新旧两份代码,才发现是这个同学为了节省一些dram的空间,把一些放置在dram上的debug用的uart cmd给注释掉了。有趣的是,其中有一道uart cmd正是用来检查cpu1的stack状态的,它引用到了SVC_Stack_1这个全局变量。当把这个cmd注释后,linker认为没有人引用到这个SVC_Stack_1就把它的length定为0,最终导致了以上的现象。把这道uart cmd重新打开之后,问题就解决了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容