Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: March 18, 2024
Understanding the meaning of error messages is an essential skill for any Linux administrator. While some errors like “No such file or directory” or “Permission denied” are clear in their meanings, others may sound a little cryptic. That is the case with the dreaded “Segmentation fault” error.
In this tutorial, we are going to learn what it is, what causes it, and how to troubleshoot the code that generates this kind of error.
In a nutshell, segmentation fault refers to errors due to a process’s attempts to access memory regions that it shouldn’t. When the kernel detects odd memory access behaviors, it terminates the process issuing a segmentation violation signal (SIGSEGV).
Lower-level languages, including C (the foundational language that Unix systems, Linux included, are built on) usually allow a great deal of flexibility on memory usage and allocation. Thus, they leave many of the memory allocation control aspects to the developer’s discretion.
While it leads to more simple and, hopefully, faster binary compiled code, it’s more prone to programming errors and oversights in memory usage.
In Linux, the segmentation fault can occur in the following conditions:
At first glance, it seems that only obvious errors would lead to those conditions. However, that is not true.
Errors like dereferencing null, non-initialized, or freed pointers (variables that reference memory areas), buffer, or stack overflows, can occur after very common programming mistakes.
For instance, calling functions with incorrect or non-initialized pointers as reference parameters, or recursive functions with failing stop conditions can result in a segmentation fault.
Let’s see a very simple code snippet that will generate a segmentation violation:
void main (void) {
char *buffer; /* Non initialized buffer */
buffer[0] = 0; /* Trying to assign 0 to its first position will cause a segmentation fault */
}
We can compile and run it:
$ ulimit -S -c unlimited
$ gcc -o seg_fault -ggdb seg_fault.c
$ ./seg_fault
Segmentation fault (core dumped)
The ulimit command enables the generation of the process’s memory dump on errors. The compiling is done with gcc, the –ggdb option on the compile will insert debug info on the resulting binary.
In addition, we enabled the debug information and the core dumping so we can take a look at where the error occurred:
$ gdb ./seg_fault /var/crash/core.seg_fault
... <snip> ...
Reading symbols from ./seg_fault...
[New LWP 6291]
Core was generated by `./seg_fault'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055ea4064c135 in main () at seg_fault.c:4
4 buffer[0] = 0;
However, if we don’t have to debug information in the code, we would still get some useful information, like the name of the function name where that is giving errors.
When programming using pointers, references, and memory arrays, we have to ensure all memory accesses are within the correct boundaries and that they comply with current access restrictions.
More specifically, we must double-check things like:
Additionally, these tips are important not only to increase code robustness but for security also. Moreover, some of those flaws might open our code to attack vectors like malicious code insertion or denial of service exploitation.
In this article, we have briefly discussed the “Segmentation fault” error, its causes, and how to pinpoint its occurrence in our code.