如何使用 GCC/Clang 编译器知道/限制 C 程序中的静态堆栈大小? [英] How to know/limit static stack size in C program with GCC/Clang compiler?

查看:58
本文介绍了如何使用 GCC/Clang 编译器知道/限制 C 程序中的静态堆栈大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个嵌入式程序,它使用一个已知大小的静态有限堆栈区域(换句话说,我有 X 字节的堆栈,并且没有覆盖操作系统可以按需分配更多堆栈).我想在运行时避免错误,并在构建时捕获它们 - 如果我在运行时错误地在某些函数块中声明了太多不适合堆栈的变量,则有一些指示.

I'm writing an embedded program that uses a static limited stack area of a known size (in other words, I have X bytes for the stack, and there's no overlaying OS that can allocate more stack on demand for me). I want to avoid errors during runtime, and catch them in build time instead - to have some indication if I mistakenly declared too much variables in some function block that won't fit in the stack during the runtime.

鉴于我没有在我的程序中使用递归调用,我能否在编译期间以某种方式知道我的所有局部变量在最深的函数调用路径上将占用多少堆栈空间?或者,如果编译器不够聪明,无法在所有嵌套调用中对其进行分析,那么至少知道我的变量在单个块(函数)中将占用多少空间?

Given that I don't use recursive calls in my program, can I somehow know during compilation time how much space on stack all my local variables will take on the deepest function call path? Or at least know how much space my variables will take in a single block (function) if the compiler is not smart enough to analyze it on all the nested calls?

推荐答案

鉴于我没有在我的程序中使用递归调用,我能否在编译期间以某种方式知道我的所有局部变量将在最深的函数调用路径上占用多少堆栈空间?

Given that I don't use recursive calls in my program, can I somehow know during compilation time how much space on stack all my local variables will take on the deepest function call path?

仅当您不使用中断时.这在任何嵌入式系统中都是极有可能的.因此,您必须通过动态分析找出堆栈使用情况.

Only if you don't use interrupts. Which is extremely likely in any embedded system. So you'll have to find out stack use with dynamic analysis.

老派的方法是在从调试器重置时将整个堆栈区域设置为 0xAA 之类的值,然后让程序运行一段时间,确保激发所有用例.然后停下来检查内存中还有多远的 0xAA.这不是一种 100% 科学、万无一失的方法,但在绝大多数情况下在实践中效果很好.

The old school way is to set your whole stack area to a value like 0xAA upon reset from a debugger, then let the program run for a while, make sure to provoke all use-cases. Then halt and inspect how far down you still have 0xAA in memory. It isn't a 100% scientific, fool-proof method but works just fine in practice, in the vast majority of cases.

其他方法涉及在您不希望程序结束的某些堆栈位置设置写断点,有点像硬件堆栈金丝雀".运行程序并确保断点永远不会触发.如果是,则从那里开始调查,将断点进一步向下移动到内存映射以查看确切位置.

Other methods involve setting write breakpoints at certain stack locations where you don't expect the program to end up, sort of like a "hardware stack canary". Run the program and ensure that the breakpoint never triggers. If it does, then investigate from there, move the breakpoint further down the memory map to see exactly where.

另一个好的做法是始终对您的堆栈进行内存映射,以便它只能溢出到禁止内存中或至少溢出到只读闪存等中 - 理想情况下,您会收到堆栈溢出的硬件异常.您肯定希望避免堆栈溢出到其他 RAM 部分,例如 .data/.bss,因为这会导致严重且极其微妙的错误情况.

Another good practice is to always memory map your stack so that it can only overflow into forbidden memory or at least into read-only flash etc - ideally you'd get a hardware exception for stack overflow. You definitely want to avoid the stack overflowing into other RAM sections like .data/.bss, as that will cause severe and extremely subtle error scenarios.

这篇关于如何使用 GCC/Clang 编译器知道/限制 C 程序中的静态堆栈大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆