Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect possible / potential stack overflow problems in a c / c++ program?

Is there a standard way to see how much stack space your app has and what the highest watermark for stack usage is during a run?

Also in the dreaded case of actual overflow what happens?

Does it crash, trigger an exception or signal? Is there a standard or is it different on all systems and compilers?

I'm looking specifically for Windows, Linux and Macintosh.

like image 652
KPexEA Avatar asked Oct 14 '08 01:10

KPexEA


People also ask

How do you detect stack overflow?

A method of detecting stack overflows is to create a canary space at the end of each task. This space is filled with some known data. If this data is ever modified, then the application has written past the end of the stack.

How can we detect possible potential stack overflow problems in ac C++ program?

One way to retrieve the exact location of the stack is to look at the file /proc/1234/maps (where 1234 is the process ID of your program). Once you know these bounds you can compute how much of your stack is used by looking at the address of the latest local variable.

What causes a stack overflow in C?

The most-common cause of stack overflow is excessively deep or infinite recursion, in which a function calls itself so many times that the space needed to store the variables and information associated with each call is more than can fit on the stack. An example of infinite recursion in C.

What is a situation that might result in a stack overflow?

A stack overflow is a type of buffer overflow error that occurs when a computer program tries to use more memory space in the call stack than has been allocated to that stack.


2 Answers

On Windows a stack overflow exception will be generated.

The following windows code illustrates this:

#include <stdio.h> #include <windows.h>  void StackOverFlow() {   CONTEXT context;    // we are interested control registers   context.ContextFlags = CONTEXT_CONTROL;    // get the details   GetThreadContext(GetCurrentThread(), &context);    // print the stack pointer   printf("Esp: %X\n", context.Esp);    // this will eventually overflow the stack   StackOverFlow(); }  DWORD ExceptionFilter(EXCEPTION_POINTERS *pointers, DWORD dwException) {   return EXCEPTION_EXECUTE_HANDLER; }  void main() {   CONTEXT context;    // we are interested control registers   context.ContextFlags = CONTEXT_CONTROL;    // get the details   GetThreadContext(GetCurrentThread(), &context);    // print the stack pointer   printf("Esp: %X\n", context.Esp);    __try   {     // cause a stack overflow     StackOverFlow();   }   __except(ExceptionFilter(GetExceptionInformation(), GetExceptionCode()))   {     printf("\n****** ExceptionFilter fired ******\n");   } } 

When this exe is run the following output is generated:

Esp: 12FC4C Esp: 12F96C Esp: 12F68C ..... Esp: 33D8C Esp: 33AAC Esp: 337CC  ****** ExceptionFilter fired ****** 
like image 113
jussij Avatar answered Sep 20 '22 09:09

jussij


On Linux you get a segmentation fault if your code tries to write past the stack.

The size of the stack is a property inherited between processes. If you can read or modify it in the the shell using commands like ulimit -s (in sh, ksh, zsh) or limit stacksize (tcsh, zsh).

From a program, the size of the stack can be read using

#include <sys/resource.h> #include <stdio.h>  int main() {     struct rlimit l;     getrlimit(RLIMIT_STACK, &l);     printf("stack_size = %ld\n", l.rlim_cur);     return 0; } 

I don't know of a standard way to get the size of the available stack.

The stack starts with argc followed by the contents of argv and a copy of the environment, and then your variables. However because the kernel can randomize the location of the start of the stack, and there can be some dummy values above argc, it would be wrong to assume that you have l.rlim_cur bytes available below &argc.

One way to retrieve the exact location of the stack is to look at the file /proc/1234/maps (where 1234 is the process ID of your program). Once you know these bounds you can compute how much of your stack is used by looking at the address of the latest local variable.

like image 30
adl Avatar answered Sep 21 '22 09:09

adl