Introduction to the

This article introduces the following contents

  • The concept of the stack
  • Why does stack overflow occur
  • Stack overflow of several chestnuts
  • How to prevent and detect stack overflow.

What is a stack?

  • From the data structure: stack (stack), also known as stack, it is a linear table with limited operation. Defines linear tables that only perform insert and delete operations at the end of the table. This end is called the top of the stack, and the other end is called the bottom of the stack. Adding a new element to a stack is also called pushing, pushing, or pushing. It is done by placing the new element on top of the top element to make it the new top element. To remove an element from a stack is also called to stack or unstack. It is to remove the top element from the stack so that the adjacent element becomes the new top element.

  • In computer systems: the stack is a dynamic memory region with the above properties. Programs can push data onto or off the stack. In the I386 machine, the top of the stack is located by a register called ESP. A pushdown reduces the address at the top of the stack, and a pop-up increases it.

  • Stack plays an important role in the running of the program. Most importantly, the stack holds the maintenance information needed for a function call, often referred to as stack frames or active records. A stack frame generally contains the following information:

    • Temporary variables: Includes non-static local variables of a function and other temporary variables automatically generated by the compiler.
    • The return address and arguments of the function

What is stack overflow?

A stack overflow is a type of buffer overflow. Overwrites of useful storage units due to buffer overflows often have unexpected consequences. In order to temporarily access data during the running of the program, it is generally necessary to allocate some memory space, which is usually called the buffer. If more data is written to a buffer than is contained in the buffer, the storage unit outside the buffer will be overwritten. This phenomenon is called a buffer overflow. The buffer length is generally related to the type of the buffer variable defined by the user. A stack overflow is a type of buffer overflow.

What is the size of the iOS/Mac stack?

  • On iOS, the main thread stack size is 1MB
  • On iOS, the stack size of child threads is 512KB
  • The main thread stack size on Mac OS is 8MB
  • For child threads, the stack size is created when the thread is created, but memory is allocated only when it is actually used. Also, the minimum stack size allowed by a child thread is 16KB, and the stack size must be an integer multiple of 4KB.

What can cause stack overflow

  • The size of the stack variable allocated directly exceeds the size of the stack space, as follows
   int buf[1024*1024] = {0};
Copy the code

The corresponding crash log is usually foundStack GuardKeyword, indicating stack overflow

  • Indirect use of out-of-memory functions on the operation stack, including but not limited to the following functions
void *memcpy(void *__dst, const void *__src, size_t __n);
void *memmove(void *__dst, const void *__src, size_t __len);
char *strcpy(char *__dst, const char *__src);
char *strncpy(char *__dst, const char *__src, size_t __n);
Copy the code

Here’s an example:

void function1(char *str){
    int32_t maxsize = 100*1024*1024;
    char buffer[maxsize];
    //strcpy(buffer, str);
    memcpy(buffer, str, maxsize);
}

   char *a = malloc(1024*1024);
   function1(a);
Copy the code

Get a crash log, keywords orStack GuardOh.

  • Infinite recursive calls, see the following Fibonacci sequence function recursive implementation
int  fibonacci(int n){
    if (n == 1) {
       return 1;
    }
    if (n == 2) {
        return 2;
    }
    return  fibonacci(n) * fibonacci(n - 1);
}
Copy the code

Here’s another crash log for everyone, free, keywords orStack Guard! _

How do I avoid stack overflow crashes?

  • Do not apply for more than 512KB of memory on the stack. You are advised to use the memory allocation method on the heap if the memory allocation exceeds 100KB.malloc.callocEtc.
  • When using system functions that operate on memory reads and writes, ensure that large memory operations are performed on the heap
  • Avoid recursion; all recursion can be implemented using loops. Even if you have to use recursion, optimize and control the recursive call level (thanks @laogreen for your valuable advice).

reference

  • Baidu Encyclopedia – stack
  • Baidu Encyclopedia – Stack overflow
  • Apple Thread Management