NuttX初始化为0的全局变量的存储

近日在调试NuttX时遇到一个问题,当时的情况是:NuttX初始化时运行到注册/dev/null时进入devnull_register函数调用_inode_search函数执行到node = node->i_peer;语句时崩溃了。

事故地点

这要在命令行下调试就麻烦了,好在我有大杀器codeblocks!观察变量发现给指针node的值异常,而node是在_inode_search函数开始赋值为g_root_inode:

node指针的初始化

可是g_root_inode是一个申明时已经初始化为NULL的全局变量:

g_root_inode的初始化

观察System.map文件找到g_root_inode的地址,在程序运行的一开始设置断点并在codeblocks的内存观察窗口中观察:

g_root_inode在内存中的值

g_root_inode的值明显异常,竟然为0xeb2ccfeb,这明显超出SRAM的地址范围,必然会引发程序运行崩溃。继续观察System.map文件终于发现了点猫腻,g_root_inode竟然被分配在了.bss段:

g_root_inode在内存中的位置

可是g_root_inode明明在申明时已经初始化过了啊,不是该分配到.data段吗?网上查询资料并查阅gcc手册才发现一个天大的公开秘密:gcc默认将出初始化为0的全局变量分配至.bss段以减小flash占用空间!GCC有一个special option控制这样的行为:

-fno-zero-initialized-in-bss

If the target supports a BSS section, GCC by default puts variables that are initialized to zero into BSS. This

can save space in the resulting code. This option turns off this

behavior because some programs explicitly rely on variables going to

the data section. E.g., so that the resulting executable can find the

beginning of that section and/or make assumptions based on that.

The default is:-fzero-initialized-in-bss.

于是乎通过sparc-gaisler-elf-gcc -v --help命令查询我所使用的sparc-gaisler-elf-gcc是否支持该命令:

sparc-gaisler-elf-gcc的bss段分配选项

出乎意料的时确实查询到了-fzero-initialized-in-bss,却没查到关闭该设置的选项-fno-zero-initialized-in-bss,姑且认为帮助信息里遗漏了该选项吧!直接在编译选项中加上该选项进行实验:

设置-fno-zero-initialized-in-bss编译选项

重新编译后观察System.map文件发现g_root_inode变量果然被分配到.data段了:

g_root_inode被分配到.data段

看来-fno-zero-initialized-in-bss选项对sparc-gaisler-elf-gcc编译器同样适用。

问题虽然能解决,但这不是个好的解决方案,因为会占用过多的flash,而且有些不对劲,因为相关资料表明:.bss段在程序加载时由操作系统初始化(DSP裸机程序进入main函数前由_int00库函数初始化),而NuttX就是个操作系统,显然.bss应该由NuttX程序来初始化!看来是我少写了一段代码。参考NuttX的stm32的启动代码我才发现我问题所在,stm32的启动代码中有专门的代码来初始化.bss段:

stm32的启动代码中.bss段的初始化

知道问题所在就好办了,参考stm32的启动代码在up_lowinit函数中添加.bss段初始化代码:

在up_lowinit函数中添加.bss段初始化

之后去掉-fno-zero-initialized-in-bss选项重新编译以再次将g_root_inode分配至.bss段,编译后观察System.map文件如下:

再次将g_root_inode分配至.bss段

在codeblocks中将nuttx.elf加载至SRAM中运行,在事故地点_inode_search函数中观察内存中g_root_inode的值:

内存中g_root_inode的值

至此问题圆满解决!得出的两个经验:

1、gcc默认将初始化为0的全局变量分配至.bss段;

2、.bss段需要人工初始化;

3、可通过-fno-zero-initialized-in-bss选项将初始化为0的全局变量分配至.data段。

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

推荐阅读更多精彩内容