Skip to main content
2 of 4
typo
heemayl
  • 58.1k
  • 9
  • 129
  • 144

The full sequence of events is:

  1. A user-space process executes a machine instruction that accesses a page of the address space that is either unmapped (there is no physical RAM there at all) or inaccessible in that fashion (write access to a read-only page, for instance).
  2. The CPU suspends execution of the offending process, and transfers control to the kernel with a memory protection exception.
  3. The kernel determines that this is due to an unrecoverable error and not, say, a page that needs to be retrieved from the swap space.
  4. The kernel sends the offending process a SIGSEGV signal. The default behavior of this signal is to terminate a process that receives it. A program can override that by installing a handler for the signal, in which case something else rather more complicated would happen, but let's assume it has not done this.
  5. Therefore, the kernel terminates the offending process, which has all the same effects as calling _exit - open files are closed, memory is deallocated, etc.
  6. The kernel notifies the parent process, via another signal (SIGCHLD) and/or via one of the wait family of system calls, that one of its children has exited. In your examples, the parent process is running a shell program, but it doesn't have to be: any process can create children and then wait for them to exit.
  7. The notification to the parent process includes information about how the process exited; in this case, that it was terminated due to a SIGSEGV signal.
  8. The parent process may, if it wishes, report this information by printing a message. Shell programs almost always do this.

Your crsh doesn't include the code for step 8, but it happens anyway, because system runs /bin/sh "under the hood". crsh is the grandparent in this scenario; the parent-process notification is fielded by /bin/sh, which prints its usual message. Then /bin/sh itself exits, since it has nothing more to do, and the C library's implementation of system receives that exit notification. You can see that exit notification in your code, by inspecting the return value of system; but it won't tell you that the grandchild process died on a segfault, because that was consumed by the intermediate shell process.

zwol
  • 7.5k
  • 2
  • 21
  • 33