114

What is the root cause of the segmentation fault (SIGSEGV), and how to handle it?

Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
Vaibhav
  • 6,620
  • 11
  • 47
  • 72

7 Answers7

128

Wikipedia has the answer, along with a number of other sources.

A segfault basically means you did something bad with pointers. This is probably a segfault:

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

Or this:

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

Or maybe this:

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

Same basic principle in each case - you're doing something with memory that isn't yours.

Chris Lutz
  • 73,191
  • 16
  • 130
  • 183
24

There are various causes of segmentation faults, but fundamentally, you are accessing memory incorrectly. This could be caused by dereferencing a null pointer, or by trying to modify readonly memory, or by using a pointer to somewhere that is not mapped into the memory space of your process (that probably means you are trying to use a number as a pointer, or you incremented a pointer too far). On some machines, it is possible for a misaligned access via a pointer to cause the problem too - if you have an odd address and try to read an even number of bytes from it, for example (that can generate SIGBUS, instead).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • The different error signals here are poorly defined - here on OS X, `char *c = NULL; *c;` actually generates a SIGBUS rather than a SIGSEGV. – Chris Lutz Oct 14 '09 at 05:29
  • 1
    Yes - both SIGBUS and SIGSEGV are somewhat system and/or processor specific. Both mean you are abusing memory. Neither is healthy. – Jonathan Leffler Oct 14 '09 at 06:17
10

SigSegV means a signal for memory access violation, trying to read or write from/to a memory area that your process does not have access to. These are not C or C++ exceptions and you can’t catch signals. It’s possible indeed to write a signal handler that ignores the problem and allows continued execution of your unstable program in undefined state, but it should be obvious that this is a very bad idea.

Most of the time this is because of a bug in the program. The memory address given can help debug what’s the problem (if it’s close to zero then it’s likely a null pointer dereference, if the address is something like 0xadcedfe then it’s intentional safeguard or a debug check, etc.)

One way of “catching” the signal is to run your stuff in a separate child process that can then abruptly terminate without taking your main process down with it. Finding the root cause and fixing it is obviously preferred over workarounds like this.

7

using an invalid/null pointer? Overrunning the bounds of an array? Kindof hard to be specific without any sample code.

Essentially, you are attempting to access memory that doesn't belong to your program, so the OS kills it.

MichaelM
  • 5,518
  • 2
  • 30
  • 23
6

Here is an example of SIGSEGV.

root@pierr-desktop:/opt/playGround# cat test.c
int main()
{
     int * p ;
     * p = 0x1234;
     return 0 ;
}
root@pierr-desktop:/opt/playGround# g++ -o test test.c  
root@pierr-desktop:/opt/playGround# ./test 
Segmentation fault

And here is the detail.

How to handle it?

  1. Avoid it as much as possible in the first place.

    Program defensively: use assert(), check for NULL pointer , check for buffer overflow.

    Use static analysis tools to examine your code.

    compile your code with -Werror -Wall.

    Has somebody review your code.

  2. When that actually happened.

    Examine you code carefully.

    Check what you have changed since the last time you code run successfully without crash.

    Hopefully, gdb will give you a call stack so that you know where the crash happened.


EDIT : sorry for a rush. It should be *p = 0x1234; instead of p = 0x1234;

pierrotlefou
  • 39,805
  • 37
  • 135
  • 175
  • Why would assigning an invalid value to a pointer and not dereferencing that pointer SIGSEGV? – sharptooth Oct 14 '09 at 05:25
  • 1
    This program will not compile with any C++ compiler. If you add the necessary cast, it will then not crash, as it doesn't actually have any invalid memory access. – Employed Russian Oct 14 '09 at 05:27
  • Strictly speaking, forcing an arbitrary value into a pointer object can cause a C/C++ program to crash right away, without a dereference attempt (read up on "trap representations"), but that's not something most of us are likey to encounter in practice. And, of course, this is not a good example to illustrate SIGSEGV :) – AnT stands with Russia Oct 14 '09 at 05:30
  • Whenever I get segfaults, I just debug with the classic `printf()` method of slowly honing in on where the problem is. (Actually, `puts()` is possibly the best function for this purpose, since it automatically appends a newline, and thus autoflushes the output. But occasionally I need to print out variable values too.) – Chris Lutz Oct 14 '09 at 17:42
3

The initial source cause can also be an out of memory.

Makusensu
  • 279
  • 3
  • 10
  • I'm trying to find more info on this without much success. My guess is that if the process has already allocated some large block of memory and overcommit is on, once you start writing, the kernel will look for physical memory and if this fails, you get segmentation fault. Is this the case? – martinkunev Jun 28 '21 at 09:58
  • I think simply trying to allocate memory you physically don't have, or over the limit of the sandbox, will else cause a crash somewhere in the program or provoke a SIGSEGV. – Makusensu Jun 29 '21 at 16:36
1

Segmentation fault arrives when you access memory which is not declared by the program. You can do this through pointers i.e through memory addresses. Or this may also be due to stackoverflow for example:

void rec_func() { int q = 5; rec_func(); }

public int Main() { rec_func(); return 0; }

This call will keep on consuming stack memory until it's completely filled and thus finally stackoverflow happens. Note: it might not be visible in some competitive questions as it leads to timeouterror first but for those in which timeout doesn't happens its a hard time figuring out SIGSEGV.

Matt
  • 25,467
  • 18
  • 120
  • 187
NIKESH SINGH
  • 148
  • 4
  • This is throwing the exception `Exception of type 'System.StackOverflowException' was thrown.`, but not SIGSEGV. – Matt Mar 15 '23 at 15:28