Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do system calls return EFAULT instead of sending a segfault?

To be clear, this is a design rather than an implementation question

I want to know the rationale behind why POSIX behaves this way. POSIX system calls when given an invalid memory location return EFAULT rather than crashing the userspace program (by sending a sigsegv), which makes their behavior inconsistent with userspace functions.

Why? Doesn't this just hide memory bugs? Is it a historical mistake or is there a good reason for it?

like image 356
Joseph Garvin Avatar asked Mar 07 '12 16:03

Joseph Garvin


People also ask

How segfault works?

A segmentation fault occurs when a program attempts to access a memory 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 a read-only location, or to overwrite part of the operating system).

What is a segmentation fault in linux?

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).


1 Answers

Because system calls are executed by the kernel, not by the user program --- when the system call occurs, the user process halts and waits for the kernel to finish.

The kernel itself, of course, isn't allowed to seg fault, so it has to manually check all the address areas the user process gives it. If one of these checks fails, the system call fails with EFAULT. So in this situation a segmentation fault hasn't actually happening --- it's been avoided by the kernel explicitly checking to make sure all the addresses are valid. Hence it makes sense that no signal is sent.

In addition, if a signal were sent, there'd be no way the kernel could attach a meaningful program counter to the signal, the user process isn't actually executing when the system call is running. This means there'd be no way for the user process to produce decent diagnostics, restart the failed instruction, etc.

To summarise: mostly historical, but there is actual logic to the reasoning. Like EINTR, this doesn't make it any less irritating to deal with.

like image 198
David Given Avatar answered Sep 26 '22 03:09

David Given