signals and inter process
play

Signals and Inter-Process Paper reading assigned for next class - PDF document

2/21/20 COMP 790: OS Implementation COMP 790: OS Implementation Housekeeping Signals and Inter-Process Paper reading assigned for next class Communication Don Porter 1 2 1 2 COMP 790: OS Implementation COMP 790: OS Implementation


  1. 2/21/20 COMP 790: OS Implementation COMP 790: OS Implementation Housekeeping Signals and Inter-Process • Paper reading assigned for next class Communication Don Porter 1 2 1 2 COMP 790: OS Implementation COMP 790: OS Implementation Logical Diagram Last time… Binary Memory • We’ve discussed how the OS schedules the CPU Threads Formats Allocators – And how to block a process on a resource (disk, network) User Today’s Lecture System Calls Kernel Process • Today: Coordination – How do processes block on each other? RCU File System Networking Sync – And more generally communicate? Memory CPU Device Management Scheduler Drivers Hardware Disk Net Consistency Interrupts 3 4 3 4 COMP 790: OS Implementation COMP 790: OS Implementation Outline What is a signal? • Signals • Like an interrupt, but for applications – Overview and APIs – <64 numbers with specific meanings – Handlers – A process can raise a signal to another process or thread – Kernel-level delivery – A process or thread registers a handler function – Interrupted system calls • For both IPC and delivery of hardware exceptions • Interprocess Communication (IPC) – Application-level handlers: divzero, segfaults, etc. – Pipes and FIFOs • No “message” beyond the signal was raised – System V IPC – And maybe a little metadata – Windows Analogs • PID of sender, faulting address, etc. • But platform-specific (non-portable) 5 6 5 6 1

  2. 2/21/20 COMP 790: OS Implementation COMP 790: OS Implementation Example Example Pid 300 Pid 300 Pid 400 int main() { int main() { ... ... PC kill(300, SIGUSR1); signal(SIGUSR1, &usr_handler); } ... } int usr_handler() { … Register usr_handler() to handle SIGUSR1 Send signal to PID 300 7 8 7 8 COMP 790: OS Implementation COMP 790: OS Implementation Basic Model Signal Types • See man 7 signal for the full list: (varies by sys/arch) • Application registers handlers with signal or sigaction SIGTSTP – 1 – Stop typed at terminal (Ctrl+Z) • Send signals with kill and friends SIGKILL – 9 – Kill a process, for realzies – Or raised by hardware exception handlers in kernel SIGSEGV – 11 – Segmentation fault • Signal delivery jumps to signal handler SIGPIPE – 13 – Broken pipe (write with no readers) – Irregular control flow, similar to an interrupt SIGALRM – 14 – Timer SIGUSR1 – 10 – User-defined signal 1 SIGCHLD – 17 – Child stopped or terminated SIGSTOP – 19 – Stop a process SIGCONT – 18 – Continue if stopped API names are admittedly confusing 9 10 9 10 COMP 790: OS Implementation COMP 790: OS Implementation Language Exceptions Signal Handler Control Flow • Signals are the underlying mechanism for Exceptions and catch blocks • JVM or other runtime system sets signal handlers – Signal handler causes execution to jump to the catch block From Understanding the Linux Kernel 11 12 11 12 2

  3. 2/21/20 COMP 790: OS Implementation COMP 790: OS Implementation Alternate Stacks Nested Signals • Signal handlers execute on a different stack than • What happens when you get a signal in the signal program execution. handler? – Why? • And why should you care? • Safety: App can ensure stack is actually mapped – And avoid assumptions about application not using space below rsp – Set with sigaltstack() system call • Like an interrupt handler, kernel pushes register state on interrupt stack – Return to kernel with sigreturn() system call – App can change its own on-stack register state! 13 14 13 14 COMP 790: OS Implementation COMP 790: OS Implementation The Problem with Nesting Nested Signals int main() { • The original signal() specification was a total mess! /* ... */ – Now deprecated---do not use! Another signal signal(SIGINT, &handler); • New sigaction() API lets you specify this in detail delivered on Double free! signal(SIGTERM, &handler); – What signals are blocked (and delivered on sigreturn) return /* ... */ – Similar to disabling hardware interrupts PC Calls munmap() } • As you might guess, blocking system calls inside of a Signal Stack signal handler are only safe with careful use of int handler() { SIGINT sigaction() free(buf1); SIGTERM free(buf2); } 15 16 15 16 COMP 790: OS Implementation COMP 790: OS Implementation Application vs. Kernel Example • App: signals appear to be delivered roughly Mark pending immediately … signal, Pid 300 10 Pid 300 Pid 400 • Kernel (lazy): … Block on disk unblock RUNNING INTERRUPTIBLE – Send a signal == mark a pending signal in the task read! • And make runnable if blocked with TASK_INTERRUPTIBLE flag – Check pending signals on return from interrupt or syscall int main() { What happens • Deliver if pending read(); to read? PC kill(300, SIGUSR1); } int usr_handler() { … Send signal to PID 300 17 18 17 18 3

  4. 2/21/20 COMP 790: OS Implementation COMP 790: OS Implementation Interrupted System Calls Default handlers • If a system call blocks in the INTERRUPTIBLE state, a • Signals have default handlers: signal wakes it up – Ignore, kill, suspend, continue, dump core • Yet signals are delivered on return from a system call – These execute inside the kernel • Installing a handler with signal/sigaction overrides • How is this resolved? the default • The system call fails with a special error code • A few (SIGKILL) cannot be overridden – EINTR and friends – Many system calls transparently retry after sigreturn – Some do not – check for EINTR in your applications! 19 20 19 20 COMP 790: OS Implementation COMP 790: OS Implementation RT Signals Signal Summary • Default signals are only in 2 states: signaled or not • Abstraction like hardware interrupts – If I send 2 SIGUSR1’s to a process, only one may be – Some care must be taken to block other signals delivered – Easy to write buggy handlers and miss EINTR – If system is slow and I furiously hit Ctrl+C over and over, • Understand control flow from application and kernel only one SIGINT delivered perspective • Real time (RT) signals keep a count • Understand basic APIs – Deliver one signal for each one sent 21 22 21 22 COMP 790: OS Implementation COMP 790: OS Implementation Other IPC Pipes • Pipes, Sockets, and FIFOs • Stream of bytes between two processes • System V IPC • Read and write like a file handle • Windows comparison – But not anywhere in the hierarchical file system – And not persistent – And no cursor or seek()-ing – Actually, 2 handles: a read handle and a write handle • Primarily used for parent/child communication – Parent creates a pipe, child inherits it 23 24 23 24 4

  5. 2/21/20 COMP 790: OS Implementation COMP 790: OS Implementation Example FIFOs (aka Named Pipes) • Existing pipes can’t be opened---only inherited int pipe_fd[2]; int rv = pipe(pipe_fd); – Or passed over a Unix Domain Socket (beyond today’s lec) int pid = fork(); if (pid == 0) { • FIFOs, or Named Pipes, add an interface for opening close(pipe_fd[1]); //Close unused write end existing pipes dup2(pipe_fd[0], 0); // Make the read end stdin exec(“grep”, “quack”); } else { close (pipe_fd[0]); // Close unused read end … 25 26 25 26 COMP 790: OS Implementation COMP 790: OS Implementation Sockets Select • Similar to pipes, except for network connections • What if I want to block until one of several handles has data ready to read? • Setup and connection management is a bit trickier • Read will block on one handle, but perhaps miss data – A topic for another day (or class) on a second… • Select will block a process until a handle has data available – Useful for applications that use pipes, sockets, etc. 27 28 27 28 COMP 790: OS Implementation COMP 790: OS Implementation Synthesis Example: The Shell Shell Example • Almost all ‘commands’ are really binaries • Ex: ls | grep foo – /bin/ls • Implementation sketch: • Key abstraction: Redirection over pipes – Shell parses the entire string – ‘>’, ‘<‘, and ‘|’implemented by the shell itself – Sets up chain of pipes – Forks and exec’s ‘ls’ and ‘grep’ separately – Wait on output from ‘grep’, print to console 29 30 29 30 5

Recommend


More recommend