【Linux】Segmentation Fault

Posted by 西维蜀黍 on 2021-03-07, Last Modified on 2021-10-17

Segmentation Fault

In computing, a segmentation fault (often shortened to segfault) or access violation is a fault, or failure condition, raised by hardware with memory protection, notifying an operating system (OS) the software has attempted to access a restricted area of memory (a memory access violation). On standard x86 computers, this is a form of general protection fault. The OS kernel will, in response, usually perform some corrective action, generally passing the fault on to the offending process by sending the process a signal. Processes can in some cases install a custom signal handler, allowing them to recover on their own, but otherwise the OS default signal handler is used, generally causing abnormal termination of the process (a program crash), and sometimes a core dump.

Category

访问了不属于进程地址空间的内存

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int* p = (int*)0xC0000fff;
     *p = 10;
} 

还有另一种可能,往受到系统保护的内存地址写数据,最常见就是给一个指针以0地址:

int  i=0;
scanf ("%d", i);  /* should have used &i */
printf ("%d\n", i);
return 0; 

Dereference a NULL Pointer

char *c = NULL;
...
*c; // dereferencing a NULL pointer

In C and C-like languages, null pointers are used to mean “pointer to no object” and as an error indicator, and dereferencing a null pointer (a read or write through a null pointer) is a very common program error. The C standard does not say that the null pointer is the same as the pointer to memory address 0, though that may be the case in practice.

This sample code creates a null pointer, and then tries to access its value (read the value). Doing so causes a segmentation fault at runtime on many operating systems.

Dereferencing a null pointer and then assigning to it (writing a value to a non-existent target) also usually causes a segmentation fault:

int *ptr = NULL;
*ptr = 1;

指针越界

char *c = "Hello";
...
c[10] = 'z'; // out of bounds, or in this case, writing into read-only memory

访问被释放的指针(freed pointer)

Freed pointer (dangling pointer, which points to memory that has been freed/deallocated/deleted)

char *c = new char[10];
...
delete [] c;
...
c[2] = 'z'; // accessing freed memory

Write Read-only Memory

#include <stdlib.h>
int main()
{
     char *c = "hello world";
     c[1] = 'H';
}

上述程序编译没有问题,但是运行时弹出SIGSEGV。此例中,”hello world”作为一个常量字符串,在编译后会被放在rodata节(GCC),最后链接生成目标程序时.rodata节会被合并到text segment与代码段放在一起,故其所处内存区域是只读的。

Reference