Green Hills中文网站 > 最新资讯 > Green Hills链接映射文件怎么看 Green Hills链接映射文件里内存段溢出怎么办
教程中心分类
Green Hills链接映射文件怎么看 Green Hills链接映射文件里内存段溢出怎么办
发布时间:2026/07/20 14:36:29

  Green Hills链接映射文件怎么查看,以及在其内部遇到内存段溢出的问题要如何处理,这件事,先得把那份map文件当成一份最终的,关于内存的账本来对待,它并不是一份普通的记录,而是链接器把各个目标文件、库文件、段落、符号和地址整理在一块儿之后得到的结果,你的程序究竟能不能被放进Flash、RAM、共享内存或者那些专用的段里面,很多情况下,不用先去把板子跑起来,而是先拿眼睛看一看这份链接映射文件,就能把问题给找出来。

  一、Green Hills链接映射文件怎么看

 

  Green Hills工程把map文件生成出来以后,刚开始的时候,不用急着去直接寻找报错的那一行,一个比较稳当的顺序,是先去瞧一瞧内存的那些区域,完了再去瞧段落是怎么分布的,到最后,才去定位到那个具体的符号,这么一来,就能知道,到底是整体的空间不够用了,还是说,仅仅只是某个模块,它自己突然之间就变大了。

 

  1、先去看内存区域是怎么样被定义的

 

  把map文件打开以后,先去寻找到【memory region】、【ROM】、【RAM】,或者是项目自己的链接脚本里面所定义的那些区域的名称,在这个地方,一般是可以看见起始地址、结束地址、还能拿来用的空间大小,以及已经被用掉的大小。

 

  比如说,代码是放在Flash里面的,运行时的数据是放在RAM里面的,还有那些中断向量、启动段、校准数据这一类的东西,又会被安放在一些固定的地址上,先要去把这些区域的情况,跟芯片手册、还有项目里的链接指令文件,去对上一对,看看是不是一致的,要是连地址本身都已经被写错了,那往后再去研究那些段落的大小,也就没有什么用处了。

 

  2、再去看section是怎么样分布的

 

  重点要去观察【.text】、【.rodata】、【.data】、【.bss】、【.sdata】、【.sbss】、【stack】和【heap】这些段落,.text这一段,它通常是代码,.rodata这一段,常常是用来放常量的,.data里面,是有初始值的那些全局变量,而.bss里面,是那些没有初始化的全局变量,在嵌入式的项目里面,.data这部分,它可能是加载在ROM里面,然后等到运行的时候,再把它给搬到RAM里去。

 

  .bss这部分,它不会去占用镜像文件的空间,可是它却会去占用运行时候的RAM,看map文件的时候,是一定要把加载地址和运行地址给分分清楚的,要是分不清楚,就很容易把空间的占用情况,给判断错了。

 

  3、最后去定位具体的对象和符号

 

  等到发现有某一个段落,它的尺寸已经很大了,这个时候,再继续往下去看,它究竟是由哪些个.o文件、库文件,还有哪些符号一起给凑出来的,比如说,RAM要是超出了限制,那也并不一定,就是整个系统全都给做得太大了,很有可能,就只是某个数组、缓存、查表,或者是用来记日志的缓冲区,它自己一下子变大了,在map文件里面,通常是可以瞧见每一个目标文件,它往里头贡献了多少大小的,就顺着那个占据空间最大的东西,一直往下追查,这个法子,是比在代码里面到处去乱猜,要来得更快一些的。

 

  二、Green Hills链接映射文件里内存段溢出怎么办

 

  在内存段发生了溢出的时候,头一步,先不要急着就去动手删除代码,而是应当先去判断一下,那个给溢出来的,到底是代码区域、常量区域、平常的RAM,还是像small data这样的,比较特殊的区域,对于不一样的段落,去处理它们的办法,也是彼此不相同的。

 

  1、先分辨清楚是哪一段发生了溢出

 

  要照着【链接报错信息】,再配上【map文件段统计】,去把它给确认下来,看看到底是.text这一段超了,.bss这一段超了,还是像.sdata、.sbss这种,属于小数据区的段落给超了,.text这一块要是超了,那一般情况下,和代码的数量、库函数、模板的实例化,还有调试方面的那些设置,是有点关系的。

 

  .bss这一块要是超了,那多半就是和全局的数组、缓存,还有静态的那些对象,有些瓜葛;至于small data那一块溢出了,则经常是和编译器那边,关于快速访问区域的限制,有些关联的,要是连段落的名称都没有给看明白,就开始去动手改动链接文件,这是很容易,就把那个麻烦,给转移到别的区域去的。

  2、去查看一下最近这段时间里变大了的模块

 

  要围绕着【目标文件大小】、【库文件贡献】,还有【全局符号】这些,去把占用增长起来的那个源头,给它找出来。

 

  要是最近一阵子,新添了诊断日志、通信缓冲区、查表数据,或者是图像的数组,那就要先去查看这些个模块,有很多RAM溢出的情况,它并不是被那些很复杂的算法给弄出来的,就只是有那么一个静态的缓冲区,它被定义得实在是太大了,好比说,一个全局的数组,它从4KB一下子就被改成了64KB,这件事放在map文件里面,是会非常明显的。

 

  3、去调整一下链接放置的策略

 

  要是发生溢出的这个原因,是在于放置的策略不太合适,那就可以再回到链接指令文件里面去,把section的映射方式,来给它调整一下,一些比较常见的做法,就包括了,把那些只读的表格,给放到ROM里面去,把那些个头比较大的缓冲区,给放到专用的RAM里面去,把那些不需要很快被访问到的数据,给移出small data这个区域,再把调试或者日志有关联的那些段落,单独给放到一个地方去,这里需要留心的一点是,在动手移动section之前,是要先去确认一下,那个目标区域是可以被访问的,对齐方面的要求也是对的,还有启动代码会把必要的那些初始化工作,都给做掉,可不要就光光是为了能够让链接这一步,可以顺利地走过去,就随随便便地去给它换一个地址。

 

  三、内存段溢出修正后怎么复查

 

  链接这一步能够通过了,这可不代表那个问题就算是结束了,在把链接文件或者是代码给改动完了以后,还要再去确认一下,镜像的布局、启动阶段的初始化,还有运行时的空间,这些地方是不是全都处在正常的状态。

 

  1、重新去生成一份map文件,然后拿来做比对

 

  改动了之后,再去重新编译一遍,把旧的那份map和新生成的那份map,它们当中各个段落的大小变化,放在一块儿去比一比,这个时候,重点要去看的是,之前溢出的那个段落,它是不是真的往下降了,还有,其他的那些段落,它们有没有出现什么不正常的增长,比如说,把常量表从RAM里面给搬到ROM里面去了以后,RAM这一边,它的确是降了,可是ROM那一边,它有可能就要挨着上限了;再比如说,把一个变量给移出了small data之后,也还要再去看看,普通的data或者是bss那一边,它是不是还能容得下它。

 

  2、检查一下stack和heap那边还剩下的余量

 

  要是只不过就是用了一些办法,让链接器勉勉强强地放了过去,可是stack、heap,还有运行的时候要用的那些缓冲区,它们那边几乎就没有留下什么余量了,那往后面,真正跑起来的时候,也还是有可能会跑崩掉的,在嵌入式的这种系统里面,链接的时候能把它给搁下,和运行的时候它能活动得开,这根本就是两码事,那些任务的栈、动态内存的分配、通信时候的缓存,还有中断嵌套这些东西,都是要放在一起去想一想的。

 

  3、把这一回溢出处理的记录,给它保留下来

 

  关于内存段这一边的调整,最好的做法,是把为什么要去动它的原因、在什么位置上做了修改、都涉及到了哪些个区域,还有最后验证出来的结果,这些信息,全给记录下来,等到往后的日子,再往上添加新的功能的时候,团队里的其他人,就能知道哪些段已经是很紧张了,哪些数据是曾经被移动过的,要是没有把记录给留下来,那么下一次,别的人再去改动链接文件的时候,很可能又会把同样的问题,再一次给带回来。

  总结

 

  Green Hills链接映射文件怎么看,以及在它里面内存段溢出怎么办,这中间的核心,是先要从内存的区域那里,去看一个总体,再从section那里,去看分布的情形,最后再从目标文件和符号那里,去把具体的来源给定位出来,在内存段发生溢出的时候,需要把代码区、数据区、bss、小数据区,还有堆栈的空间,都给分得清清楚楚,这之后,再去决定,是要去减小对象的体积,还是去挪动段落,是去调整链接的脚本,还是去重新规划一下内存的布局,只要把map文件给看明白了,很多链接方面的问题,也就不必靠着反复地去试错,才能去解决了。

135 2431 0251