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.

[参考译文] TMS320F280039:SPRA820中的堆栈溢出检测始终是有效的?

Guru**** 2394305 points
Other Parts Discussed in Thread: C2000WARE, SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1345752/tms320f280039-stack-overflow-detection-in-spra820-is-always-effective

器件型号:TMS320F280039
主题中讨论的其他器件:C2000WARESysConfig

应用报告 SPRA820 提出了一种检测堆栈溢出的方法、但我对其真正的有效性存疑。

在该应用中、定义了一个小窗口(8个字)、由一个观察点监控、靠近有效栈的末尾(较低地址)-请参阅上面文档中的第3.1节。 当某些代码开始对监测的空间进行重新编号时、只是因为堆栈指针向该区域的最下方移动、会触发某个事件以向其发送信号。 乍一看、这似乎是一个足够好的解决方案、但我怀疑在调用这样的函数时(始终)这一点是正确的:

int  foo(int x)

{

    int    buffer[100];

    int    var = x;

    ...

}

如果 μ`buffer`恰巧从起始分配 之前 监控窗口和结束 之后 它、从不 完全地 写入时、不能保证它会触发溢出。 同时、μ`var`单独分配可以修改意外区域中的数据(远低于堆栈区域)。 此函数甚至可以在销毁有价值的数据后成功返回、而不留下任何迹线。

在我看来、这种考虑是否成立了?

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

    尊敬的 Luca:

    本应用手册是在 ERAD 支持之前创建的。 F28003x 上的 ERAD 应更易于使用并在我们的 TRM 中有更好的记录。 我们在 C2000WARE SDK 中已经有一个示例、该示例展示了使用 ERAD 模块进行堆栈溢出检测的情况。 我强烈建议参考我们的示例、以开始进行堆栈溢出检测。

    此致!

    马瑞安

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

    您好、Ryan、
    文件中的示例erad_ex3_stack_overflow_detect.c和文件中的 SysConfig 外设的 erad_ex3_stack_overflow_detect_syscfg.c行为方式都是 SPRA820中所示的检测方法、即使使用 driverlib API、这些示例代码非常清晰简短。

    将我的示例的两个变量声明添加到函数中recursiveFunction()应该会再次暴露出溢出的可能性。 正如预期的那样,应该有某种访问buffer(假设它的最后一个元素)和var验证他们的存在,或者他们可以优化和消失。
    很抱歉、我无法检验我的假设、因为我正处于设计分析阶段、还没有真正的硬件。

    此外、C2000ware 示例使用掩码然后,他们捕获对单个地址的访问权限,而不是像原来的8字块。 当然、可以通过修改掩码值来更改此值。

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

    您好、Lucas:

    可能是我误解了这个问题。 您是否可以发送测试案例、揭示您的假设?

    此致!

    马瑞安

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

    从 C2000Ware 中导入了示例至
     C:\ti\c2000\C2000Ware_5_02_00_00\driverlib\f28003x\examples\ERAD\application_owned_examples
    已命名
     erad_ex3_stack_overflow_detect_syscfg

    然后、我修改了现有的recursiveFunction()、添加了以下代码和注释进行说明:

    // Dummy, just to justify a global access
    volatile uint32_t dummyValue = 0;

    //
    // recursive function to fill the stack
    //
    void recursiveFunction(uint32_t delay)
    {
        // Reserves space on stack: if not written, it won't trigger
        // a stack overflow
        uint32_t    buffer[100];
        // This assignment alone can already be below the
        // lower stack position
        uint32_t    clobber = delay;
        // When overflowing, it *can* happen to have stack as in:
        //  ;[Stack higher address]
        //   [previous calls, etc.]                     ; +   Allowed stack
        //   [return address, frame pointer, ...]       ; +
        //  FP + buffer + 99           : .space 020h    ; +
        //                               .space ...     ; +
        //  __TI_STACK_END - THRESHOLD : .space ...     ; +   [Watch point]
        //                               .space ...     ; +
        //  __TI_STACK_END             : .space ...     ; +   [Stack ends here!]
        //                               .space ...     ; ///  Forbidden area
        //  FP + buffer + 0            : .space 020h    ; ///
        //  FP + clobber               : .space 020h    ; ///
        //
        //  Here (__TI_STACK_END - THRESHOLD) falls between local buffer start
        //  address and buffer end address, and it's the only address checked
        //  for access by the watchpoint in ERAD.
        //  Any write access to `buffer` lower positions, or to `clobber`
        //  will violate a forbidden area

        functionCallCount++;

        // The following lines are here just to give a meaning to
        // local variables, so that they aren't considered unused;
        // buffer[1] ... buffer[99] are untouched
        buffer[0] = functionCallCount + 1;
        dummyValue = clobber + buffer[0];

        //
        // Recursive function
        //
        recursiveFunction(delay + 1UL);
    }

    同时保存已生成 ASM 的列表似乎证实了我的怀疑。 `buffer`的大部分空间是未触控的,然后观测点可以被解除触发,而下面的空间可以被阻断。

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

    尊敬的 Luca:

    感谢您提供此内容。 我将使用示例进行研究、并咨询这里的一些人、看看我们可以如何根据需要更新此示例。

    此致!

    马瑞安

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

    尊敬的 Luca:

    我已经能够复制您的发现、代码最终会在 ITRAP ISR 中完成。  

    我将与我的另一位同事协商,看看我们能为这种情况做些什么,以及是否有解决办法。

    此致!

    马瑞安

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

    尊敬的 Luca:

    我们最多可以在给定的窗口内检测写入、例如使用 ERAD 的掩码来检测0x800-0x8FF。 在 C28x 上、没有用于检测较大突变的 ERAD 解决方案。  

    最好在分配数组以写入递归函数中该数组中的每个地址时、确保 ERAD 将具有该触发器。

    此致!

    马瑞安