Detecting Stack Overflow in C Functions

Thread Starter

gogo00

Joined Oct 28, 2023
43
I have a question about stack memory usage in C functions. As far as I understand, local variables are stored in the stack memory. Suppose we have a stack size limit of 1KB, and we've written a C function where we declare and initialize multiple variables, potentially exceeding the 1KB limit.

My question is: How can we determine i our unction's stack memory usage exceeds the allocated stack size without?

has anyone experienced exceeding the available stack size inadvertently?
 

Papabravo

Joined Feb 24, 2006
21,258
Generally speaking, the required information may not be readily available at runtime. To make the required information available, you might consider modifying the "C" initialization assembly language file to make available to the C-Linker, the stack beginning and ending values. In this fashion you could then decide when and where to check the stack pointer to see if it is within limits. This would avoid additional overhead on every function call. Once you get to the called function it may be too late if the function requires a large stack frame and additional local storage.
 

Thread Starter

gogo00

Joined Oct 28, 2023
43
Write a known value into absolute memory beyond the end of stack.
If the value is changed then you can assume stack overflow.
I want to share my understanding that the term "stack overflow" has a specific meaning related to the stack memory of a program being exhausted due to excessive recursion or large stack allocations. Writing beyond the end of a stack-allocated buffer in C language doesn't directly cause a stack overflow; instead, it can lead to memory corruption or undefined behavior.

When we write beyond the bounds of a stack-allocated array in C, we're essentially accessing memory that hasn't been explicitly reserved for our use. This can overwrite other data on the stack
 
I want to share my understanding that the term "stack overflow" has a specific meaning related to the stack memory of a program being exhausted due to excessive recursion or large stack allocations. Writing beyond the end of a stack-allocated buffer in C language doesn't directly cause a stack overflow; instead, it can lead to memory corruption or undefined behavior.

When we write beyond the bounds of a stack-allocated array in C, we're essentially accessing memory that hasn't been explicitly reserved for our use. This can overwrite other data on the stack
That makes sense to me.

Suppose we have a stack size limit of 1KB, and we've written a C function where we declare and initialize multiple variables, potentially exceeding the 1KB limit.
I think you mean that the function has been allocated 1KB of stack space. You don't mean that the total size of the stack is 1KB.
The 1KB of stack space was allocated by the build tools based on the total space required by the function's local variables. You aren't talking about the case where a function is a thread and the thread's stack size can be chosen by you.
Have I understoon correctly?

I think you want to detect when a function uses some memory in the stack, outside of the stack space allocated to the function that it is not supposed to use. Is that what you want?

If so, it's not going to be simple to detect. Consider that some function A calls function B. Function A passes the address of one of its stack variables to function B. Now function B can legitimately access some memory on the stack outside of its own stack space.
 

MrChips

Joined Oct 2, 2009
30,931
In a typical system, the application is allocated memory space in what is known as the application heap. Here is a typical map of the application heap.

1715790409324.png

The lowest memory location is shown as location 0 at the bottom of the heap. The highest memory location is shown as high at the top of the heap. Space for user variables are usually allocated in increasing memory location. Meanwhile, the stack starts at high and occupies decreasing memory locations indicated in the grey area.

A stack overflow condition occurs when writing to the stack collides with user variable space. When this happens user data gets corrupted as well as stack data. Program crash is the usual end result.
 

BobTPH

Joined Jun 5, 2013
9,128
The amount of stack space available when a function is called varies during execution depending on what other functions are active. You can determine how much stack space a function needs, but just because it is less than the available stack space does not guarantee that it will not cause a stack overflow when running.

Say you always call this function directly from main. There will be some amount of stack space in use at the time of the call. The call itself will generally take 1 word (address sized word) for the return address. Once called, the function will save any registers it might use so they can be restored. You likely have used anywhere from 2 to 10 stack locations before you even get to local variables. To determine ahead of time whether a stack overflow might occur, you would need to determine the stack space used by all functions that might be activated at any given time, this includes at least main and probably several functions in the language's library startup code.

So, no, there is no easy way to determine how much stack space your program will take without running it. If you have a debugger, you can step into the function and see where the stack pointer is after it has allocated space then compare it to the lowest (or highest) stack location depending on which way the stack grows. That direction also varies between different microcontrollers.
 

ApacheKid

Joined Jan 12, 2015
1,658
I have a question about stack memory usage in C functions. As far as I understand, local variables are stored in the stack memory. Suppose we have a stack size limit of 1KB, and we've written a C function where we declare and initialize multiple variables, potentially exceeding the 1KB limit.

My question is: How can we determine i our unction's stack memory usage exceeds the allocated stack size without?

has anyone experienced exceeding the available stack size inadvertently?
This depends on the hardware, for example if a virtual memory manager is operating then the space "outside" of the stack can be assigned to non-existent virtual pages and so an exception can be triggered if code tries to access that, some operating systems leverage this.

Stratus' VOS had this feature, search the docs here for the term "fence".

1716223007108.png
 

WBahn

Joined Mar 31, 2012
30,239
I have a question about stack memory usage in C functions. As far as I understand, local variables are stored in the stack memory. Suppose we have a stack size limit of 1KB, and we've written a C function where we declare and initialize multiple variables, potentially exceeding the 1KB limit.

My question is: How can we determine i our unction's stack memory usage exceeds the allocated stack size without?

has anyone experienced exceeding the available stack size inadvertently?
It largely depends on the details of the memory manager that the compiler embeds into your program, as well as the capabilities of the OS and hardware and how tightly tied they are to the program's configuration.

Most memory managers will take the allocated memory and start the stack at one end and the heap at the other and let them grow toward each other. This allows for automatic flexibility for when the program needs lots of stack but little heap or vice versa. Detecting that the stack has encroached on the heap's space that is actually in use is certainly something that the memory manager is capable of doing, but there is likely a significant performance penalty associated with it.

Yes, I have had programs run out of stack space. This was back in the x386 days on machines that had a few megabytes of RAM. I think the stack space was just a handful of kilobytes. I was a very new C programmer at the time and didn't even know what a stack was, let alone where various types of variables were allocated, so I was putting a bunch of arrays on the stack and my program blew up -- which is how I learned about stacks, and where various types of variables were allocated, and how to keep my stack from blowing up.
 
Top