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/TM4C1294NCPDT:HeapTrack:A_BufOverlow

Guru**** 2461020 points
Other Parts Discussed in Thread: 66AK2H14, SYSBIOS

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/651797/rtos-tm4c1294ncpdt-heaptrack-a_bufoverlow

器件型号:TM4C1294NCPDT
Thread 中讨论的其他器件:66AK2H14SYSBIOS

工具/软件:TI-RTOS

CCS 6.1.3
tirtos_tivac_2_16_01_14 (BIOS_6_45_02_31)
xdctools_3_32_00_06_core
TI-CGT-ARM_15.12.1.LTS

我可以在修改的示例"EVENT_EK_TM4C1294XL_TI_TivaTM4C1294NCPDT"上看到一个 heaptrack 溢出错误。 请参阅附件。

"EVENT_EK_TM4C1294XL_TI_TivaTM4C1294NCPDT_2"是已修改的、"EVENT_EK_TM4C1294XL_TI_TivaTM4C1294NCPDT_0"是原始的。

请帮您了解一下。

e2e.ti.com/.../event_5F00_EK_5F00_TM4C1294XL_5F00_TI_5F00_TivaTM4C1294NCPDT_5F00_0.zip

e2e.ti.com/.../event_5F00_EK_5F00_TM4C1294XL_5F00_TI_5F00_TivaTM4C1294NCPDT_5F00_2.zip


谢谢

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

    您可以使用"EVENT_EK_TM4C1294XL_TI_TivaTM4C1294NCPDT_3":如果邮件发布失败、则释放分配的缓冲区。

    我已检查是否存在栈溢出。 注意堆栈大小设置为4K。

    e2e.ti.com/.../event_5F00_EK_5F00_TM4C1294XL_5F00_TI_5F00_TivaTM4C1294NCPDT_5F00_3.zip

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

    我可能已经发现了这个问题、但我需要进一步研究。 该网站的大部分内容将于下周推出、因此我将于1月2日与您进行跟进。

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

    [引用 user="ToddMullanix"]我可能找到了问题、但我需要再看一下。Todd、我还能够使用 来自 Jianyi 的示例程序重复失败。

     HeapTrack_free()函数检测 到 HeapTrack_STARTSCRIBBLE 不正确,导致 HeapTrack_a_bufOverflow 升高。

    通过使用硬件观察点来观察写入错误的涂鸦值的时间,跟踪到 HeapTrack_alloc()函数在以下调用中将条目插入堆跟踪器队列:

    /*排队进入堆的链接列表*/
    Queue_put (trackQueue、&(tracker->queElem)); 

    注意  到 HeapTrack_alloc ()调用的 Queue_put ()函数在修改链接列表时禁用 Hwi:

    void Queue_put (Queue_Object *对象、Queue_elm * elem)
    {
    UINT 键;
    
    KEY = Hwi_disable();
    
    elem->next =&(obj->elem);
    elem->prev = obj->elem.prev;
    obj->elem.prev->next = elem;
    obj->elem.prev = elem;
    
    Hwi_restore (key);
    } 

    而  HeapTrack_free ()调用的 Queue_remove()函数在修改链接列表时不会禁用 Hwi:

    void Queue_remove (Queue_elm * qelem)
    {
    #if defined (__IAR_systems_icc_)
    PTR temp;
    temp = qelem->next;
    qelem->prev->next = temp;
    temp = qelem->prev;
    qelem->next ->prev = temp;
    #else
    qelem->prev->next = qelem->next;
    qelem->next ->prev = qelem->prev;
    #endif
    } 

    因此、如果使用 HeapTrack 执行分配/释放多个任务、则认为存在竞争条件、即 HeapTrack 维护的分配队列可能会变为无效、从而导致 HeapTrack 损坏内存。

    作为一个实验、修改 了 Queue_remove()来禁用 Hwi、并且该示例现在已运行更长时间而不会出现故障(在发生更改之前发生了20、000、000次迭代、但发生了131、000次迭代)。 鉴于疑似问题是比赛条件、需要进一步努力证明这确实是个问题。

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

    切斯特、您好!

    是的。 我今天参加了检查自周五开始运行的测试。 我还在 HeapTrack_free()中的 Queue_remove()周围添加了一个 Hwi_disable/restore 函数,但它仍然在被调用。 它确实是对 Queue_remove()的非原子调用。 很烦人,因为我写了代码:(

    Jianyi、您能否在 HeapTrack_free()中的 Queue_remove()周围添加 Hwi_disable()/Hwi_restore()并重建 BIOS? 这是否可以解决您的问题?

    Todd

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

    大家好、 我将进行测试。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Chester、
    我想知道如何使用 HW 观察点来调试谁覆盖了划线? 因为分配和要释放的缓冲区地址是不同的、所以脚本的地址也是不同的。 我认为硬件观察点只能用于固定位置。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Jianyi Bao ]我想知道如何使用硬件观察点来调试谁覆盖了划线? 因为分配和要释放的缓冲区地址是不同的、所以脚本的地址也是不同的。 在这种情况 下、当 A_BufOverlow 发生脚本的地址时、它的错误值与从运行到运行的值相同。 因此、我能够设置一个硬件观察点、以在问题发生时捕获到写入到带有错误值的字节地址。

    同意如果故障不是在运行到运行的相同划线地址和值处发生、则无法使用硬件观察点来调试覆盖。

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

    [引用 user="Chester Gillon">因此,如果使用 HeapTrack 执行多个任务分配/释放,则认为 HeapTrack 维护的分配队列可能会变为无效,从而导致 HeapTrack 损坏内存。要查看使用 HeapTrack 是否会损坏应用程序正在使用的内存, 除了破坏 HeapTrack 划线的值外、将该示例修改为:

    a)使 CreateMsg()函数在动态分配的缓冲区中放置测试模式。

    b)使 readertask()函数在释放缓冲区之前验证动态分配缓冲区中的测试模式。

     readertask()的输出报告了在中检测到测试模式的字节的情况,即"numIncorrectDataBytes"。

    修改后的示例显示 ,在 HeapTrack 检测到 a_bufOverflow 错误之前,readertask()可以检测几个字节的损坏:

    Event_ID_02
    读取 id 的隐式过帐= 272678 (numIncorrectDataBytes=0)
    Event_ID_02的隐式过帐
    读取 id = 282777 (numIncorrectDataBytes=0)
    Event_ID_02的隐式过帐
    读取 id = 292878 (numIncorrectDataBytes=0)
    读取 SYSIncorrectDataBytes=302486 (numIncorrectDataBytes=3041
    
    )的隐式过载:NumberInoverflow = 3041:读取操作失败
    xdc.runtime.Error.raise::numberIncorrectDataBytBytBytes=3041.rings.influ.influ.intrack 

    更新后的示例随附 在 e2e.ti.com/.../event_5F00_EK_5F00_TM4C1294XL_5F00_TI_5F00_TivaTM4C1294NCPDT.zip 上

    在 修改队列时将 Queue_remove()更改为禁用 HWI,还可以防止应用程序检测到测试模式的损坏,以及防止 a_bufOverflow。

    编辑:在对 Queue_remove()进行更改之后,运行了70,000,000次迭代,没有错误,而在更改之前,在大约302,000次迭代之后失败。

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

    [引用 user="ToddMullanix">我也在 HeapTrack_free ()的 Queue_remove ()周围添加了 Hwi_disable/restore 函数、但它仍在继续充值。 为了与 HeapMem.c 实现方式保持一致、它似乎是对 Queue_remove ()的非原子调用。[/引用]Todd、而是 在 Queue_remove ()周围添加 Hwi_disable/restore 应该 在 HeapTrack.c 或 Queue.c 中使用 Gate_enterModule/Gate_leaveModule?

    HeapTrack 能否"继承"底层堆使用的门?

    从 SYS/BIOS 的角度来看、我肯定会注意到禁用 HWI .va 的好处。 使用门(可配置为保护并发访问免受任务、SWI 或 HWI 的影响)。

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

    [引用 USER="Chester Gillon">作为一个实验、修改 了 Queue_remove()以禁用 Hwi、该示例现在已运行更长时间而不发生故障尝试创建一个更简单的示例以演示故障仅使用两个 SYS/BIOS 任务、即没有 SWI、其中的任务是:

    a)在无限循环中包含以下内容的 WRITE_TASK:

    -调用 malloc()以分配伪随机字数的缓冲区。

    -用一个测试模式(递增序列)填充缓冲器。

    -对于包含到缓冲区指针、缓冲区大小和测试模式开始的消息、使用 Mailbox_post (BIOS_wait_forever)。

    b)在无限循环中包含以下内容的 READ_TASK:

    -调用 Mailbox_pend (BIOS_wait_forever)等待来自 write_task 的消息。

    -验证缓冲区中测试模式的内容。

    -调用 free()以释放由 write_task 分配的缓冲区。

    在单核 TM4C129上运行这两个任务程序时、无法重复该故障。 HeapTrack 中的故障条件是当  另一个任务位于  HeapTrack_freert()的 Queue_remove()中时,任务必须从 HeapTrack_alloc()调用 Queue_put ()。 对于单核器件、任务调度不会触发故障条件。

    因此、在66AK2H14的 Cortex-A15内核上运行该程序、其中 SYS/BIOS 6.50.1.12配置为 SMP 模式、用于四个内核。 将 write_task 和 read_task 的关联性设置为不同的内核、以使任务"并行"运行。 在启用了 HeapTrack 且没有 SYS/BIOS 修改的情况下、程序会快速失败、从而:

    a) READ_TASK 在测试模式中检测到一个损坏的字、大约每25条消息一次。

    b)在1000条消息内、由于 SYS/BIOS 错误、测试停止。 在十个运行中出现了以下类型的 SYS/BIOS 错误:

    - ti_sysbios_b堆_HeapTrack_free__E 函数中的数据中止异常。

    - HeapTrack 由于 划字不正确而引发了 A_bufOverflow 断言失败。

    - HeapMem 提出 了 a_invalidFree 断言失败。

    以下修改阻止了 SMP 模式测试失败:

    1)禁用 HeapTrack (在运行30、000、000条消息后没有错误)。

    2)保持 HeapTrack 被启用、并修改 修改 的 Queue_remove()来禁用/启用 Hwi (在针对150,000,000条消息保持运行后没有错误)。

    这还表明、当多个任务可以执行分配/释放时、HeapTrack 会受到竞争状态的影响。

    SMP 示例项目随附 在 e2e.ti.com/.../66AK2H14_5F00_A15_5F00_sys_5F00_bios_5F00_heap_5F00_track.zip 上。 它设置为在设置为"DSP 不引导"模式的 EVMK2H 上运行,并使用由所有四个 Cortex-A15内核组成的同步组加载程序。

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

    您好!

     经过一些测试、我认为通过在 Queue_remove 中禁用和恢复 HWI、此问题已得到解决。 谢谢。

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

    感谢您的更新。 修复方法是在调用 Queue_remove 之前禁用 HeapTrack_free 中的中断。 我们记录 Queue_remove()不是原子函数。 在 Queue_remove 中添加 Hwi_disable/restore 将略微影响对 Queue_remove 的其他调用的性能、因为没有添加值。

    错误编号为 SYSBIOS-604:HeapTrack_free 以非原子方式调用 Queue_remove

    Todd