1. Introduction
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.
2. What Is Segmentation Fault?
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.
3. What Causes Segmentation Faults?
In Linux, the segmentation fault can occur in the following conditions:
- Segment Violation Mapping Error (SEGV_MAPERR): Accessing memory outside the application’s address space
- Segment Violation Access Error (SEGV_ACCERR): Accessing memory where the application has no permission or trying to write on read-only memory space
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.
4. Example
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.
5. How to Prevent Segmentation Faults?
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:
- Dynamic memory allocation
- Indirect memory access through pointers
- Array indexes with values higher than their current allocated sizes
- Type consistency throughout the code and function parameters calling convention
- String and buffer operations
- Pointer and buffer allocations (watch-out for non-allocated pointers)
- Stop conditions in recursive functions
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.
6. Conclusion
In this article, we have briefly discussed the “Segmentation fault” error, its causes, and how to pinpoint its occurrence in our code.