Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikipediaThe Free Encyclopedia
Search

Segmentation fault

From Wikipedia, the free encyclopedia
(Redirected fromSIGSEGV)
Computer fault caused by access to restricted memory
"Segfault" redirects here. For the website, seeSegfault (website).
This articleneeds additional citations forverification. Please helpimprove this article byadding citations to reliable sources. Unsourced material may be challenged and removed.
Find sources: "Segmentation fault" – news ·newspapers ·books ·scholar ·JSTOR
(November 2011) (Learn how and when to remove this message)

Incomputing, asegmentation fault (often shortened tosegfault) oraccess violation is afault, or failure condition, raised by hardware withmemory protection, notifying anoperating system (OS) the software has attempted to access a restricted area of memory (a memory access violation). On standardx86 computers, this is a form ofgeneral protection fault. The operating systemkernel will, in response, usually perform some corrective action, generally passing the fault on to the offendingprocess by sending the process asignal. Processes can in some cases install a custom signal handler, allowing them to recover on their own,[1] but otherwise the OS default signal handler is used, generally causingabnormal termination of the process (a programcrash), and sometimes acore dump.

Segmentation faults are a common class of error in programs written in languages likeC that provide low-level memory access and few to no safety checks. They arise primarily due to errors in use ofpointers forvirtual memory addressing, particularly illegal access. Another type of memory access error is abus error, which also has various causes, but is today much rarer; these occur primarily due to incorrectphysical memory addressing, or due to misaligned memory access – these are memory references that the hardwarecannot address, rather than references that a process is notallowed to address.

Many programming languages have mechanisms designed to avoid segmentation faults and improve memory safety. For example,Rust employs an ownership-based[2] model to ensure memory safety.[3] Other languages, such asLisp andJava, employgarbage collection,[4] which avoids certain classes of memory errors that could lead to segmentation faults.[5]

Overview

[edit]
Example of human generated signal
Segmentation fault affectingKrita inKDE desktop environment
Anull pointerdereference onWindows 8

A segmentation fault occurs when a program attempts to access amemory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (for example, attempting to write to aread-only location, or to overwrite part of theoperating system).

The term "segmentation" has various uses in computing; in the context of "segmentation fault", it refers to the address space of aprogram.[6] With memory protection, only the program's own address space is readable, and of this, only thestack and the read/write portion of thedata segment of a program are writable, while read-only data allocated in the const segment and thecode segment are not writable. Thus attempting to read outside of the program's address space, or writing to a read-only segment of the address space, results in a segmentation fault, hence the name.

On systems using hardwarememory segmentation to providevirtual memory, a segmentation fault occurs when the hardware detects an attempt to refer to a non-existent segment, or to refer to a location outside the bounds of a segment, or to refer to a location in a fashion not allowed by the permissions granted for that segment. On systems using onlypaging, aninvalid page fault generally leads to a segmentation fault, and segmentation faults and page faults are both faults raised by thevirtual memory management system. Segmentation faults can also occur independently of page faults: illegal access to a valid page is a segmentation fault, but not an invalid page fault, and segmentation faults can occur in the middle of a page (hence no page fault), for example in abuffer overflow that stays within a page but illegally overwrites memory.

At the hardware level, the fault is initially raised by thememory management unit (MMU) on illegal access (if the referenced memory exists), as part of its memory protection feature, or an invalid page fault (if the referenced memory does not exist). If the problem is not an invalid logical address but instead an invalid physical address, abus error is raised instead, though these are not always distinguished.

At the operating system level, this fault is caught and a signal is passed on to the offending process, activating the process's handler for that signal. Different operating systems have different signal names to indicate that a segmentation fault has occurred. OnUnix-like operating systems, a signal called SIGSEGV (abbreviated fromsegmentation violation) is sent to the offending process. OnMicrosoft Windows, the offending process receives a STATUS_ACCESS_VIOLATIONexception.

Causes

[edit]

The conditions under which segmentation violations occur and how they manifest themselves are specific to hardware and the operating system: different hardware raises different faults for given conditions, and different operating systems convert these to different signals that are passed on to processes. The proximate cause is a memory access violation, while the underlying cause is generally asoftware bug of some sort. Determining theroot causedebugging the bug – can be simple in some cases, where the program will consistently cause a segmentation fault (e.g., dereferencing anull pointer), while in other cases the bug can be difficult to reproduce and depend on memory allocation on each run (e.g., dereferencing adangling pointer).

The following are some typical causes of a segmentation fault:

  • Attempting to access a nonexistent memory address (outside process's address space)
  • Attempting to access memory the program does not have rights to (such as kernel structures in process context)
  • Attempting to write read-only memory (such as code segment)

These in turn are often caused by programming errors that result in invalid memory access:

  • Dereferencing anull pointer, which usually points to an address that's not part of the process's address space
  • Dereferencing or assigning to an uninitialized pointer (wild pointer, which points to a random memory address)
  • Dereferencing or assigning to a freed pointer (dangling pointer, which points to memory that has been freed/deallocated/deleted)
  • Abuffer overflow
  • Astack overflow
  • Attempting to execute a program that does not compile correctly. (Some compilers[which?] will output anexecutable file despite the presence of compile-time errors.)

In C code, segmentation faults most often occur because of errors in pointer use, particularly inC dynamic memory allocation. Dereferencing a null pointer, which results inundefined behavior, will usually cause a segmentation fault. This is because a null pointer cannot be a valid memory address. On the other hand, wild pointers and dangling pointers point to memory that may or may not exist, and may or may not be readable or writable, and thus can result in transient bugs. For example:

char*p1=NULL;// Null pointerchar*p2;// Wild pointer: not initialized at all.char*p3=malloc(10*sizeof(char));// Initialized pointer to allocated memory// (assuming malloc did not fail)free(p3);// p3 is now a dangling pointer, as memory has been freed

Dereferencing any of these variables could cause a segmentation fault: dereferencing the null pointer generally will cause a segfault, while reading from the wild pointer may instead result in random data but no segfault, and reading from the dangling pointer may result in valid data for a while, and then random data as it is overwritten.

Handling

[edit]

The default action for a segmentation fault or bus error isabnormal termination of the process that triggered it. Acore file may be generated to aid debugging, and other platform-dependent actions may also be performed. For example,Linux systems using the grsecurity patch may log SIGSEGV signals in order to monitor for possible intrusion attempts usingbuffer overflows.

On some systems, like Linux and Windows, it is possible for the program itself to handle a segmentation fault.[7] Depending on the architecture and operating system, the running program can not only handle the event but may extract some information about its state like getting astack trace,processor register values, the line of the source code when it was triggered, memory address that was invalidly accessed[8] and whether the action was a read or a write.[9]

Although a segmentation fault generally means that the program has a bug that needs fixing, it is also possible to intentionally cause such failure for the purposes of testing, debugging and also to emulate platforms where direct access to memory is needed. On the latter case, the system must be able to allow the program to run even after the fault occurs. In this case, when the system allows, it is possible to handle the event and increment the processor program counter to "jump" over the failing instruction to continue the execution.[10]

Examples

[edit]
Segmentation fault on anEMV keypad

Writing to read-only memory

[edit]

Writing to read-only memory raises a segmentation fault. At the level of code errors, this occurs when the program writes to part of its owncode segment or the read-only portion of thedata segment, as these are loaded by the OS into read-only memory.

Here is an example ofANSI C code that will generally cause a segmentation fault on platforms with memory protection. It attempts to modify astring literal, which is undefined behavior according to the ANSI C standard. Mostcompilers will not catch this at compile time, and instead compile this to executable code that will crash:

intmain(void){char*s="hello world";*s='H';}

When the program containing this code is compiled, the string "hello world" is placed in therodata section of the programexecutable file: the read-only section of thedata segment. When loaded, the operating system places it with other strings andconstant data in a read-only segment of memory. When executed, a variable,s, is set to point to the string's location, and an attempt is made to write anH character through the variable into the memory, causing a segmentation fault. Compiling such a program with a compiler that does not check for the assignment of read-only locations at compile time, and running it on a Unix-like operating system produces the followingruntime error:

$gccsegfault.c-g-osegfault$./segfaultSegmentation fault

Backtrace of the core file fromGDB:

ProgramreceivedsignalSIGSEGV,Segmentationfault.0x1c0005c2inmain()atsegfault.c:66*s='H';

This code can be corrected by using an array instead of a character pointer, as this allocates memory on stack and initializes it to the value of the string literal:

chars[]="hello world";s[0]='H';// equivalently, *s = 'H';

Even though string literals should not be modified (this has undefined behavior in the C standard), in C they are ofstatic char [] type,[11][12][13] so there is no implicit conversion in the original code (which points achar * at that array), while in C++ they are ofstatic const char [] type, and thus there is an implicit conversion, so compilers will generally catch this particular error.

Null pointer dereference

[edit]

In C and C-like languages,null pointers are used to mean "pointer to no object" and as an error indicator, anddereferencing 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 tomemory address 0, though that may be the case in practice. Most operating systems map the null pointer's address such that accessing it causes a segmentation fault. This behavior is not guaranteed by the C standard. Dereferencing a null pointer isundefined behavior in C, and a conforming implementation is allowed to assume that any pointer that is dereferenced is not null.

int*ptr=NULL;printf("%d",*ptr);

This sample code creates anull 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;

The following code includes a null pointer dereference, but when compiled will often not result in a segmentation fault, as the value is unused and thus the dereference will often be optimized away bydead code elimination:

int*ptr=NULL;*ptr;

Buffer overflow

[edit]
Main article:Buffer overflow

The following code accesses the character arrays beyond its upper boundary. Depending on the compiler and the processor, this may result in a segmentation fault.

chars[]="hello world";charc=s[20];

Stack overflow

[edit]
Main article:Stack overflow

Another example isrecursion without a base case:

intmain(void){returnmain();}

which causes thestack to overflow which results in a segmentation fault.[14] Infinite recursion may not necessarily result in a stack overflow depending on the language, optimizations performed by the compiler and the exact structure of a code. In this case, the behavior of unreachable code (the return statement) is undefined, so the compiler can eliminate it and use atail call optimization that might result in no stack usage. Other optimizations could include translating the recursion into iteration, which given the structure of the example function would result in the program running forever, while probably not overflowing its stack.

See also

[edit]

References

[edit]
  1. ^Expert C programming: deep C secrets By Peter Van der Linden, page 188
  2. ^"The Rust Programming Language - Ownership".
  3. ^"Fearless Concurrency with Rust - The Rust Programming Language Blog".
  4. ^McCarthy, John (April 1960)."Recursive functions of symbolic expressions and their computation by machine, Part I".Communications of the ACM.4 (3):184–195.doi:10.1145/367177.367199.S2CID 1489409. Retrieved2018-09-22.
  5. ^Dhurjati, Dinakar; Kowshik, Sumant; Adve, Vikram; Lattner, Chris (1 January 2003)."Memory safety without runtime checks or garbage collection"(PDF).Proceedings of the 2003 ACM SIGPLAN conference on Language, compiler, and tool for embedded systems. Vol. 38. ACM. pp. 69–80.doi:10.1145/780732.780743.ISBN 1581136471.S2CID 1459540. Retrieved2018-09-22.
  6. ^"Debugging Segmentation Faults and Pointer Problems - Cprogramming.com".www.cprogramming.com. Retrieved2021-02-03.
  7. ^"Cleanly recovering from Segfaults under Windows and Linux (32-bit, x86)". Retrieved2020-08-23.
  8. ^"Implementation of the SIGSEGV/SIGABRT handler which prints the debug stack trace".GitHub. Retrieved2020-08-23.
  9. ^"How to identify read or write operations of page fault when using sigaction handler on SIGSEGV?(LINUX)". Retrieved2020-08-23.
  10. ^"LINUX – WRITING FAULT HANDLERS". 12 November 2017. Retrieved2020-08-23.
  11. ^"6.1.4 String literals".ISO/IEC 9899:1990 - Programming languages -- C.
  12. ^"6.4.5 String literals".ISO/IEC 9899:1999 - Programming languages -- C.
  13. ^"6.4.5 String literals".ISO/IEC 9899:2011 - Programming languages -- C.
  14. ^"What is the difference between a segmentation fault and a stack overflow?".Stack Overflow. Retrieved2023-11-11.

External links

[edit]
Look upsegmentation fault in Wiktionary, the free dictionary.
General
Variants
Kernel
Architectures
Components
Process management
Concepts
Scheduling
algorithms
Memory management,
resource protection
Storage access,
file systems
Supporting concepts
System failure
Application failure
Device and data errors
Other
Lists
Related
Retrieved from "https://en.wikipedia.org/w/index.php?title=Segmentation_fault&oldid=1220172090"
Categories:
Hidden categories:

[8]ページ先頭

©2009-2025 Movatter.jp