为了缩小固件体积,把运行时库从Full改成Normal,重新构建却出现未定义符号;或者调试配置能够链接,发布配置却报错。这类问题不能只靠来回切换库选项解决。运行时库还与目标处理器、编译参数、底层输入输出接口及已有静态库有关。定位时,应保留完整错误信息,查清报错符号由谁引用、预期由哪里提供。以下以IAR Embedded Workbench for Arm的常见英文界面为例,其他目标平台需对应检查。
map文件里显示栈占用不大,运行时却出现栈空间不足,这两个结果为什么对不上?先要分清看到的是什么:链接器计算的是调用链的静态栈需求,调试器显示的栈水位则来自本次运行留下的内存痕迹。它们各有用途,也各有盲区。下面以使用ILINK和C-SPY的IAR Embedded Workbench for Arm为例,说明报告生成及差异核查方法。
工程编译成功后,输出目录里常会先看到一个.out文件。若烧录工具要求BIN,不能直接把它改名为.bin:IAR需要先完成链接,再通过输出转换器生成指定格式。动手前最好看一眼烧录工具要求的是BIN还是HEX,以及它是否要求单独填写写入地址。下面以IAR Embedded Workbench for Arm为例说明。
改了一个源文件,按下编译,窗口却只提示工程已是最新;换个时候,构建中途停了,翻来翻去又找不到具体错误。这种情况容易让人以为IAR漏了消息。其实构建窗口显示的是这一次构建产生的内容:如果文件没有参与编译,或窗口内容被清空,之前的错误不会留在那里。下面以IAR Embedded Workbench for Arm为例,从打开窗口开始检查。
IAR Embedded Workbench编译工程时,可以针对Debug和Release分别设置代码优化级别。优化打开后,编译器可能删除没有实际用途的局部变量、把变量暂存在寄存器中、调整语句执行顺序,或者直接把函数展开到调用位置,所以C-SPY里看到的变量状态可能和源码不完全对应。常见表现包括变量显示Unavailable、局部变量突然消失、单步执行顺序跳动以及断点无法停在某一行。碰到这些现象时,要先确认工程实际使用的优化配置,再判断是调试信息显示变化,还是程序运行结果真的出了问题。
IAR Embedded Workbench运行C/C++程序时,局部变量、函数调用现场和部分中断上下文会占用栈空间,malloc、calloc以及C++的new等动态分配则会使用堆。程序平时运行正常,一进入深层函数、复杂中断或者处理较大局部数组就出现HardFault、随机复位、变量值异常,很可能和栈空间有关。判断这类问题时,可以把C-SPY运行时监控、链接器静态分析和ICF中的内存配置放在一起看,也要把堆空间不足和栈溢出分开。