0

The above-mentioned GCC flag has caused some confusion for me.
Here it says the following:

-Wstack-usage=byte-size

Warn if the stack usage of a function might exceed byte-size. The computation done to determine the stack usage is conservative. Any space allocated via alloca, variable-length arrays, or related constructs is included by the compiler when determining whether or not to issue a warning.

So what does "The computation done to determine the stack usage is conservative." mean?

I linked a small program written in C++ and intentionally used -Wstack-usage=1 to see the warnings and stack usages for various functions.

A few of the warning messages can be seen below:

Util.cpp: In function 'getCharInput.constprop':
Util.cpp:113:6: warning: stack usage is 64 bytes [-Wstack-usage=]
  113 | void util::getCharInput( char* const inputBuffer, const std::streamsize streamSize )
      |      ^
Main.cpp: In function 'main':
Main.cpp:10:5: warning: stack usage is 112 bytes [-Wstack-usage=]
   10 | int main( )
      |     ^

Why the stack usage of main is only 112 bytes despite that it calls all the other functions? Doesn't it keep the callee on its stack frame until the callee returns and gets deleted from the stack frame of main? I might have the wrong knowledge though.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
digito_evo
  • 3,216
  • 2
  • 14
  • 42
  • Should we guess not seeing your code? – 273K Dec 25 '21 at 20:19
  • @S.M. The code is small but still probably more than 2000 LOC. How do you expect me to show it? Go [here](https://github.com/Kasra-coder/magical-creations/tree/master/src) if you really need to see it. – digito_evo Dec 25 '21 at 20:22
  • @digito_evo See this: [mcve] – eerorika Dec 25 '21 at 20:28
  • @S.M. So I guess I might have understood something in the wrong way. Because a few of the functions have 240, 912, etc. stack usages. And they are called once by `main` and that's why I am confused. I guess the linker does not check the call stack of every single function and just reports the size of each function's own scope. – digito_evo Dec 25 '21 at 20:40
  • @KamilCuk So you mean it assumes that all the callees inside a caller have a size of 0 and then only computes the stack usage of the caller? – digito_evo Dec 25 '21 at 21:04
  • 5
    @Kamil, no that's not what it means. Saying it is "conservative" means that it tends to overestimate the stack usage, so it will be more likely to issue a warning if there is uncertainty in the estimate. – prl Dec 25 '21 at 23:11

1 Answers1

2

Why the stack usage of main is only 112 bytes despite that it calls all the other functions?

Stack usage is calculated by GCC is for this function only. This is also in the documentation: "Warn if the stack usage of a function might exceed byte-size".

Doesn't it keep the callee on its stack frame until the callee returns and gets deleted from the stack frame of main?

Yes, so when executing that code that happens. GCC does not statically traverse the whole call stack. It just calculates stack usage just for one specific function and checks if the usage of that single specific functions is greater than some threshold.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Oh, so this is the part that I was wrong. The linker does not check the call stack of each function. I got it. – digito_evo Dec 25 '21 at 20:44
  • Is there a way I can check the whole stack usage of a program? And also what is the limit for stack usage on Windows and GCC (mingw-64)? When does an overflow happen? – digito_evo Dec 25 '21 at 20:46
  • 2
    `Is there a way I can check the whole stack usage of a program?` The problem is not possible to solve generally (recursive functions). Anyway https://stackoverflow.com/questions/389219/how-to-determine-maximum-stack-usage https://stackoverflow.com/questions/126036/checking-stack-usage-at-compile-time and similar links on google. `what is the limit for stack..` No idea. `When does an overflow happen?` Search on Wikipedia what is an stack overflow. – KamilCuk Dec 25 '21 at 20:48
  • Thanks for the links. Someone has mentioned [stackanalyzer](https://www.absint.com/stackanalyzer/index.htm) but it's not free. Do you think there is a tool in Visual Studio 2022 that can help me check the stack usage while running the program? – digito_evo Dec 25 '21 at 21:24
  • I do not know, I do not use that thing. – KamilCuk Dec 25 '21 at 21:39
  • @digito_evo: IIRC, the Windows default stack-growth limit is 1 MiB, vs. Linux's default of 8 MiB. If your program tries to move the stack pointer farther down than that, and then access that memory, the kernel treats the resulting #PF page fault as invalid, instead of triggering further growth. Exactly like you accessed any invalid pointer. – Peter Cordes Dec 26 '21 at 19:11
  • @Peter Cordes That was informative. So how does a program request a bigger stack at runtime? I saw a document on Microsoft's website which showed a few functions to help increase the reserved stack size at runtime. Do you have any idea of whether it's true or not? – digito_evo Dec 26 '21 at 20:48
  • 1
    @digito_evo: On Windows, no idea. On Linux, you use `ulimit -s` *before* starting the program. IDK if you can `mmap` the pages below the stack region; I think they're reserved as guard pages. For new threads, you can specify it before thread creation, since a thread stack is just a normal allocation. – Peter Cordes Dec 26 '21 at 21:56