调试偶发超时或任务执行顺序异常时,断点容易改变现场,连续跟踪更适合还原问题发生前后的调用过程。不过,记录中找不到某个函数,并不能直接证明它没有执行。采集窗口、过滤条件、编译优化和代码解析都可能影响结果。使用TRACE32时,可以先确认程序流已被正确记录,再沿着函数地址、调用关系和跟踪完整性逐项核验。
一、Trace32如何查看实时跟踪与函数调用
实时跟踪通常指目标运行期间采集执行信息,常规记录窗口需要停止采集后查看。芯片跟踪模块、板级接口和探头共同决定可用功能,不能直接照搬其他处理器的配置脚本。
1、选择跟踪方式并完成一次短采集
①运行对应开发板的初始化脚本,打开【Trace】→【Configuration…】,检查当前【METHOD】。
②按硬件条件选择【Analyzer】或【Onchip】等受支持方式,确认程序流跟踪已在处理器专用配置中启用。
③点击【Init】清空旧记录,选择【Fifo】模式,检查【AutoArm】设置。
④点击【Go】运行目标,观察状态和【used】变化;复现目标动作后点击【Break】,等待跟踪状态回到【OFF】。
初次验证宜控制运行时间,让目标函数及其前后调用都落在记录范围内。循环模式会用新记录覆盖旧记录,程序运行太久,较早发生的关键调用可能已经不在缓冲区中。运行中的采集状态变化,也不能代替对最终内容的检查。
2、结合列表、统计和调用树查看函数
程序流列表用于检查执行细节,函数统计用于比较调用次数与耗时,调用树用于识别上下级关系。三个窗口应围绕同一次采集结果查看。
①打开【Trace】→【List】→【Default】,在【Trace.List】中检查地址、符号及时间信息。
②打开【Perf】→【Function Runtime】→【Show Numerical】,查看函数调用次数和运行时间。
③在目标函数上右键选择【Parents】或【Children】,检查调用者与被调用函数。
④通过【Perf】→【Function Runtime】→【Show as Tree】展开调用树,并回到记录列表核对关键位置。
二、Trace32跟踪记录缺少关键函数事件如何核验
核验时要分清函数没有进入采集范围、记录已经丢失,以及记录存在但无法正确解释。建议先保留原始结果,再调整配置重新采集,避免覆盖问题现场。
1、检查采集时间与过滤范围
过滤配置既可能限制生成哪些信息,也可能决定从何时开始、何时停止生成。只捕获函数入口事件的设置,无法提供完整的函数内部执行过程。
①在【Trace.state】中检查模式、缓冲区大小和采集状态,核对关键动作发生的时间。
②检查断点与跟踪配置中的【TraceEnable】、【TraceON】和【TraceOFF】条件。
③将开始条件前移至调用者,将结束条件后移至目标函数返回之后,再执行一次短采集。
④在【Trace.List】中点击【Find】,输入目标函数或地址,选择【Program】后搜索。
若目标函数位于记录最前端或最末端,入口或返回可能落在窗口之外。这种记录可以证明部分代码执行过,但未必能形成完整调用及可靠的耗时统计。
2、检查是否发生数据丢失或采集错误
①执行【Trace.Find FIFOFULL/ALL】,检查目标时间附近是否存在溢出。
②执行【Trace.Find FLOWERROR/ALL】,并查看相邻位置是否出现【HARDERROR】。
③根据错误类型核对跟踪端口复用、采样时序、接口速率及硬件连接。
④关闭不需要的数据跟踪或其他跟踪源,缩短记录区间后复测。
FIFO溢出表示信息生成速度超过传输处理能力,会造成跟踪包丢失;硬件错误则涉及采集数据损坏。增加记录缓冲区可以延长保留时间,却未必解决芯片内部或接口带宽不足。启用可能暂停处理器的防溢出机制前,也要评估它对时序观察的影响。
3、核对执行代码与解析所用代码
①对照本次构建产物,确认加载的【ELF】、调试符号和目标程序属于同一版本。
②在异常地址打开【List】窗口,检查代码能否读取,并通过【MAP.List】核对访问限制。
③对代码已被覆盖或目标内存不可读的情况,准备匹配的代码镜像,按需要使用【Data.LOAD.Elf文件名/VM】和【Trace.ACCESS VM】进行解析。
TRACE32通常结合压缩跟踪信息与程序指令重建执行流。出现unknown,可能是地址已经解出,但对应指令无法读取;使用了错误版本的代码,也可能导致流程重建异常。涉及重定位或动态装载时,还应核对镜像地址与执行地址是否一致。
4、检查内联优化与调用树重建
①执行【sYmbol.List.InlineFunction】,检查目标函数是否被内联。
②使用【sYmbol.INFO】查看相关调用位置,并对照反汇编确认实际生成的指令。
③打开【Trace.ListNesting】,检查关键调用附近的【!】和【?】标记。
④需要观察内联代码时,尝试使用【Trace.STATistic.sYmbol/INLINE】或【Trace.Chart.sYmbol/INLINE】。
内联函数没有独立的统一入口,源代码中的一次调用未必对应机器代码中的调用指令。嵌套列表中的异常标记则提示调用树构建存在问题,应回到程序流检查,不能直接把统计表中的缺项当作漏采。
三、Trace32如何让函数跟踪结果便于对比
同一函数的调用次数和耗时,只有在采集范围、分析范围及执行上下文一致时才适合比较。对任务切换频繁或多核运行的程序,这些条件尤其容易被忽略。
1、固定函数统计的分析区间
①在【Trace.List】中定位业务开始点,右键选择【First in Statistic】。
②定位业务结束点,右键选择【Last in Statistic】,再运行【Trace.STATistic.Func】。
③需要恢复整段分析时,选择【Full Statistic】,重新核对函数是否出现。
统计范围限制只改变分析内容,不会补回没有采集到的记录。对比两次结果时,应选取相同业务阶段,并尽量包含完整的入口和返回,避免把不同长度的记录直接比较。
2、核对任务与处理器核上下文
①在【Trace.List】中检查关键函数所在处理器核,并核对任务切换信息是否完整。
②检查分析窗口中的【CORE】或【TASK】筛选条件,确认目标执行上下文没有被排除。
③对使用虚拟地址的操作系统,核对任务识别与地址转换配置,再复查对应函数。
总结
TRACE32的函数分析建立在跟踪记录、代码镜像和执行上下文之上。关键函数缺项时,沿着采集范围、数据完整性、代码解析和编译优化检查,更容易判断问题出在哪一层。日常调试可以保留一套经过验证的短采集配置,围绕明确业务动作逐步扩大范围,让每次调整都有可比较的结果。希望这些方法能帮助你读懂跟踪中的缺项;遇到具体错误标记时,也可以结合处理器型号继续细化核验方法。