This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS/LAUNCHXL-CC1310:任务上下文中的 FREE()导致内存损坏?

Guru**** 2609895 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/583796/rtos-launchxl-cc1310-free-in-task-context-causes-memory-corruption

器件型号:LAUNCHXL-CC1310

工具/软件:TI-RTOS

您好!

几周以来、我一直在努力应对令人上瘾的崩溃、而 CCS 在帮助我解决正在发生的事情方面毫无用处。

我一直在随机拖放我的代码、打开和关闭东西、移动东西、几乎将 printf 放在任何地方、都没有结果。

一切看起来都很好,然后是 kaboom! 硬件异常、具有非传感器寄存器且无回扫。

CCS 进行了优化以提供的所有调试信息都普遍指向 TI-RTOS 内部、而不是我的任何代码。

今天(作为随机变化的一部分并希望获得最佳结果)、我尝试为静态缓冲器切换一个小型 malloc/free 对、突然崩溃消失了...

已知 TI-RTOS 的 malloc/free 实现是否被破坏?

我在其他地方使用 malloc 进行运行时对象实例化、但这些对象不会被释放、并且似乎不会导致我一直在努力的崩溃。

是的、我肯定不会调用 malloc、也不会从 Hwi 或 Swi 上下文中释放、我知道这会中断一些东西、并且我会将信标用作此类同步的目标。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Michael、

    发生这种情况时、您能否共享您看到的寄存器转储?  您是否按照 常见问题解答中的步骤 使用寄存器转储获取堆栈反向跟踪?

    [引用 user="Michael Moon "]将 printf 几乎放在任何地方,[/引用]

    您是否使用标准 printf?  我不建议这样做。 这将对程序的时间安排产生重大影响(以及您看到的问题)、并可能导致行为看起来不一致。

    建议改用 System_printf()(或 Log_print 变体之一)。

    [引用 USER="Michael Moon "]已知 TI-RTOS 的 malloc/free 实现是否被破坏?[/QUERT]

    我不知道。

    您的系统配置使用什么堆?

    Steve

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Steve、

    是的、我已经尝试了该指南中的调试步骤、但是 CCS 拒绝更新 PC、SP、LR 寄存器。 有时、它会让我更改一个值、但另两个值不会接受新值。

    具体的行为是、我可以单击该字段并输入新值、但当我按 Enter 或以其他方式取消对该字段的聚焦时、显示的值仍然是在我尝试更改它之前可见的旧值。 很明显、CCS 认为我可以编辑寄存器、但决定在它尝试实际使用新值后我不能编辑。

    我在获得可用回扫时遇到的最大问题是0)上述拒绝更新 PC/SP/LR 的问题、1) CCS 无法通过无法识别的符号进行回扫、 和2) CCS 不能通过硬件异常中断进行回写跟踪(它只显示异常描述字、例如0xFFFFFFFD 作为返回地址、并在由于#1而没有符号时产生扼流圈)

    #1是个问题、因为0x1000nnnn 存储器地址范围内的任何符号显然都没有可用的符号、并且我的反向跟踪经常会在此处出现。
    我还必须进行一些挖掘(请参阅我的其他文章)以查找0x1001nnnn 范围的符号、我还没有找到 CCS 自动加载这些符号的方法、并且我必须在每次调试运行时手动加载这些符号。 (从 golde/CC13xx/rtos_rom.xem3中添加符号)

    #2是个问题、因为我正在尝试找出硬件异常的原因-由于上面的#0、我甚至无法通过在 Hwi 触发之前将 SP 指向堆栈位置来绕过该问题。

    此外、当异常发生时、SP 通常是非感应的、但当我手动检查堆栈的存储器块时、似乎在 TI-RTOS 中发生了深刻的事件-就像 TI-RTOS 内部函数本身溢出了堆栈缓冲区、然后返回一样。
    我很少在系统和任务堆栈中找到对我自己代码的任何引用、当我这么做时、它似乎是一个完全无害的代码片段、可能已经从返回。
    发生这种情况时、 LR 寄存器始终保存0x100xnnnn 范围内的地址-如果是0x1001、我至少可以从 RTOS_ROM.xem3中获取函数名称、但如果是0x1000、我无法找到中代码的任何源或符号 这部分 ROM。

    它也不能帮助 golde/CC13xx/rtos_rom.xem3 (提供0x1001nnnn 范围的调试符号)中的文件/行号与 tirtos-2.21.00.06提供的源文件保持一致、因此即使我在 TI-RTOS 内部跟踪我的过程、 代码视图将指向注释和 ifdefs 以及空白行(当然还有随机代码)、有时会指向它认为位于其中的函数的几页。

    我一直在使用 System_printf 而不是常规 stdlib printf、其中 System_flush 位于适当的位置、SysMin 中有一个大型缓冲区。 我本应该在那里做得更具体一些。

    无论默认堆是什么、我的编译都使用、我的 cfg 仅具有 BIOS.heapSize = 0x800;。 我认为这意味着我正在使用 HeapMem。

    无论如何、在将 malloc/free 对切换为静态缓冲器(作为一系列非常长的随机代码更改的一部分)后、我的固件已在整个周末运行而不会崩溃、而不是在启动后的20至30秒内崩溃。 这个问题似乎几乎肯定是由在任务上下文中使用 malloc/free 对引起的。

    几年前、我在其他针对 cortex-m3的项目上做了大量工作、这些项目没有出现任何此类问题、并广泛使用 malloc/free -这就是为什么我甚至没有想象到、在2017年、这可能是我需要关注的问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您能告诉我您使用的是哪个版本的 TI-RTOS 吗? 我看了你的其他线程、但我没有看到任何地方提到过它。 此外、哪个版本的 CCS?

    根据您提供的各种说明、您似乎正在经历一个在存储器上进行某段代码输入的经典案例、而这种情况不应该发生。 例如、这可能会发生在损坏的指针上、然后指令会被该错误代码覆盖。 然后、当 PC 到达它时、您会遇到崩溃。

    这种问题的一个症状是、当您添加打印语句或进行看似不相关的代码更改时、应用程序将突然开始工作。 问题是、在这种情况下、您只能"幸运"、因为坏代码仍在占用内存、以至于它不应触摸、它不会崩溃、因为该内存不再是 PC 正在执行的指令(例如)。  或者、由于不同的时序(即添加的打印语句)、它仍然在同一条指令上插入、但该指令已运行、因此您不会遇到崩溃。

    不幸的是、在我看来、您好像在这里获得了幸运。

    如果您再次看到崩溃、您可以尝试的一个不同之处是将返回地址(LR)的值放入 PC (而不是 LR 寄存器)中。

    在执行 BIOS 常见问题解答主题中的步骤后、如果我没有看到堆栈跟踪、我发现这对我来说很有用。 将 LR 值放入 PC 寄存器会将我带回到代码中的实际问题点、以及在 CCS 中填充调用堆栈。

    Steve

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我使用的是 CCS 7.0.0.00043 (Linux)和 TI-RTOS 2.21.00.06

    是的、它听起来像是存储器被占用、但我在代码中找不到可能导致它的任何东西。 我在到处都有 System_printf、每次检查时、我的几个指针看起来都很好。

    我从事固件编程已超过15年、我在第一个微控制器(m68hc11)上做的第一件事之一是编写一个与 TI-RTOS 相似(但比 TI-RTOS 更原始)的抢先式多任务操作系统。 我最近参与的主要公共固件项目是 Smoothitheware、它广泛使用动态创建的对象和指向各种内容的指针。

    基本上、如果我的调试工具正常工作、我非常擅长查找内存损坏。 我以前能够使用 GDB 脚本转储各种对象格式和步行列表并打印所有内容。 我习惯随时获取返回到复位矢量的回溯、并能够查看其中任何帧发生的情况。 我习惯了调试器准确知道哪个代码行在执行什么操作、并且能够修改存储器内的内容、更新 SP 并再次尝试函数调用、而无需花费字面量分钟等待工具链执行它的操作、甚至可以针对此情况进行刷新/重置。

    如果我能够准确地找出正在占用的存储器、我只需设置一个观察点、然后找出正在执行的操作、但到目前为止、尽管我已经在使用 CCS 和 TI-RTOS 的调试工具进行数周的努力、但我仍然无法找到这一重要信息。

    在几个场合中、我发现一段特定的存储器被占用、但是在它上面设置观察点只是指我返回 TI-RTOS 中的代码、看起来它不应该执行任何类似的操作、 由于调试 TI-RTOS 内部时调试视图指向错误的代码行(或者根本不知道0x1000nnnn 部分发生了什么情况)、并且回溯不会返回到足够远的位置、 我所得到的信息非常不足、无法深入挖掘并找到根本原因。