1 / 39

Unix System Interface Programming Part 6.3 – Process and Signal

Unix System Interface Programming Part 6.3 – Process and Signal Prepared by Xu Zhenya( xzy@buaa.edu.cn ). Draft – Xu Zhenya( 2002/10/01 ) Rev1.0 – Xu Zhenya( 2002/10/10 ). Agenda. 1. Process 2. Signal. Modeling the Concepts( Relationship ). Modeling the Concepts ( Sequence ). Parent.

rafael-reed
Download Presentation

Unix System Interface Programming Part 6.3 – Process and Signal

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Unix System Interface Programming Part 6.3 – Process and Signal Prepared by Xu Zhenya( xzy@buaa.edu.cn ) Draft – Xu Zhenya( 2002/10/01 ) Rev1.0 – Xu Zhenya( 2002/10/10 )

  2. Agenda • 1. Process • 2. Signal

  3. Modeling the Concepts( Relationship )

  4. Modeling the Concepts ( Sequence ) Parent Child fork() exec() exit() abort() • The parent ignores/catches SIGCHLD. • The parent = “init” Notification by SIGCHLD Zombie wait(), waitpid(), wait3(), wait4()

  5. Process Context process-specific data structures (page tables, task and mm structs) physical memory kernel code/data/stack kernel VM 0xc0 demand-zero stack %esp process VM Memory mapped region for shared libraries .data .text libc.so brk runtime heap (via malloc) demand-zero uninitialized data (.bss) initialized data (.data) .data program text (.text) .text p forbidden 0

  6. Overview of “Process”

  7. Overview of “Process”

  8. Create a process • fork, vfork & system: textbook, p162 • Notes: • 1. Two generic use for fork: fork & no exec, fork + exec (spawn) • 2. The two main reasons for fork to fail: • 3. Why the child’s PID is returned to the parent process, and a zero to the child? • 4. The child process is a replica of the parent. • 5. Copy-on-write(COW) • 6. The interaction of fork with the I/O functions: stdio functions • 7. File Sharing • 8. Inherited properties from the parent process • 9. Properties Different from the parent process • 10. Fork() Safety in the multithreaded environment

  9. execlp execl execle build argv build argv build argv execvp execv execve Try each PATH prefix Use Environ Running a program • Notes: • In execlp/execvp, when a filename argument is specified, If filename contains a slash, it is taken as a pathname • For execl, execle, and execlp: • char *arg0, char *arg1, …, char *argn, (char *)0 • the total size of the argument list and the environment : sysconf( ARG_MAX )

  10. exec() in the kernel • To run a new program p in the current process using exec(): • free vm_area_struct’s and page tables for old areas. • create new vm_area_struct’s and page tables for new areas. • stack, bss, data, text, shared libs. • text and data backed by ELF executable object file. • bss and stack initialized to zero. • set PC to entry point in .text • The kernel will swap in code and data pages as needed. process-specific data structures (page tables, task and mm structs) physical memory same for each process kernel code/data/stack kernel VM 0xc0 demand-zero stack %esp process VM Memory mapped region for shared libraries .data .text libc.so brk runtime heap (via malloc) demand-zero uninitialized data (.bss) initialized data (.data) .data program text (.text) .text p forbidden 0

  11. Running a program • Semantic of the exec family • File descriptors open in the calling process image: close-on-exec • Directory streams open in the calling process image • Signals set to the default action (SIG_DFL) • Signals set to be caught by the calling process image: SIG_DFL • Signals set to be ignored (SIG_IGN) by the calling process image • In a shell which does not support job control, run “cc xxx &” • any functions previously registered by atexit() • If the set-user-ID mode bit of the new process image • Any shared memory segments attached to the calling process image

  12. Terminate a process (1) • Ways for a process to terminate: • Normal termination & Abnormal termination • Notify its parent how it terminated • Exit status & termination status • signal SIGCHLD: SA_NOCLDWAIT set by signaction • “zombie”: • What happened if the parent terminates before the child? • Explanations for exit(): atexit() and tmpfile()

  13. Terminate a process (2) 53 /* 54 * Exit, flushing stdio buffers if necessary. 55 */ 56 void 57 exit( status ) 58 int status; 59 { 60 register struct atexit *p; 61 register int n; 62 63 #ifdef _THREAD_SAFE 64 extern int _thread_autoinit_dummy_decl; 65 /* Ensure that the auto-initialization routine is linked in: */ 66 _thread_autoinit_dummy_decl = 1; 67 #endif 68 69 for (p = __atexit; p; p = p->next) 70 for (n = p->ind; --n >= 0;) 71 (*p->fns[n])(); 72 if (__cleanup) 73 (*__cleanup)(); 74 _exit(status); 75 }

  14. Terminate a process (3) 49 void 50 abort() 51 { 52 sigset_t mask; 53 54 /* 55 * POSIX requires we flush stdio buffers on abort 56 */ 57 if ( __cleanup ) 58 (*__cleanup)(); 59 60 sigfillset( &mask ); 61 /* 62 * don't block SIGABRT to give any handler a chance; we ignore 63 * any errors -- X311J doesn't allow abort to return anyway. 64 */ 65 sigdelset( &mask, SIGABRT ); 66 #ifdef _THREAD_SAFE 67 _thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); 68 #else 69 (void)sigprocmask( SIG_SETMASK, &mask, (sigset_t *)NULL ); 70 #endif 71 (void)kill( getpid(), SIGABRT ); 72 73 exit( 1 ); 74 }

  15. Cleaning up terminated process (1)

  16. Cleaning up terminated process (2)

  17. Cleaning up terminated process (3) • The waitpid() function provides three features that are not provided by the wait function: • waitpid() lets us wait for one particular process (whereas wait() returns the status of any terminated child). • waitpid() provides a nonblocking version of wait(). There are times where we want to fetch a child’s status, but we don’t want to block. For example, receiving the signal SIGCHLD. • waitpid() supports job control(with the WUNTRACED option). #define WIFEXITED(stat) ((int)((stat)&0xFF) == 0) #define WIFSIGNALED(stat) ((int)((stat)&0xFF) > 0 && \ (int)((stat)&0xFF00) == 0) #define WIFSTOPPED(stat) ((int)((stat)&0xFF) == 0177 && \ (int)((stat)&0xFF00) != 0) #define WEXITSTATUS(stat) ((int)(((stat)>>8)&0xFF)) #define WTERMSIG(stat) ((int)((stat)&0x7F)) #define WSTOPSIG(stat) ((int)(((stat)>>8)&0xFF))

  18. /* the init process */ handle( sig_t handler, ... ) { int sig; struct sigaction sa; sigset_t mask_everything; va_list ap; va_start( ap, handler ); sa.sa_handler = handler; sigfillset( &mask_everything ); while ( ( sig = va_arg(ap, int ) ) != NULL ) { sa.sa_mask = mask_everything; /* XXX SA_RESTART? */ sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0; sigaction( sig, &sa, (struct sigaction *) 0 ); } va_end( ap ); } Cleaning up terminated process (4)

  19. Signal Overview • Unix are designed around a virtual-machine model, in which system calls are considered to be the parallel of machines’ hardware instruction set. Signals are the software equivalent of traps or interrupt, a signal-handling routine perform the equivalent function of interrupt or trap service routines. • How does the hardware interrupt work? • Interruption source -> 8259 controller->cpu->interrupt vector table->interrupt service routines • How to write a interrupt handler? • Save the context, set the interrupt mask • May change another stack

  20. Signal Overview • => signal generation, • The kernel is the interrupt controller, • The destination process is the CPU: mask register, handler vector, etc

  21. Signal Overview • Signal Generation • Exceptions • Other processes: sigsend() • Terminal interrupts: CTRL+c • Job control: stop and continue, notify their parent process • Quotas • Notifications: aio • Alarms: setitimer(), generated by the callout thread • Actions for signal • Default, IGN, Specific Handler

  22. Signal overview • How does the kernel send a signal to the destination process? • 1. get the signal number and the process control block • 2. check PCB’s signal block mask, and ignored mask • 3. if PCB blocked this signal, then pending • 4. if PCB ignored this signal, then discarded now. • *** in Solaris, semantics of SIGCHLD • 5. if PCB has a signal hander installed for this signal • What is the destination process doing now? • If sleeping for a system call, then wakeup it now. • Put the signal into the process’ signal-q.

  23. Signal overview • Signal handling: • only be taken by the receiving process itself, so the process must be scheduled to run. • The receiving process becomes aware of the signal when the kernel does check for pending signal. The kernel checks at the following times: • Before returning to user mode from a system call or interrupt. • Just before blocking on an interruptible event. • Immediately after waking up from an interruptible event. • How does the kernel prepare the context for the signal handler? • Stack frame: signum, siginfo_t, ucontext *, and a instruction which will re-enter the kernel again • Nested signal handling??? Very Difficult.

  24. Signal overview • Conclusions: • Signals generated by asynchronous events may occur after any instruction in the code path of the process. • We need mechanisms to block the specific signals during running. The most progress in O.S. design • Book, p6-7 • In multithreaded program, signal handling becomes rather difficult there. • In Solaris’s implementation, signal handling is difficult too. • Generation -> notification -> redirect -> delivered • There is a LWP to wait for signals, and then dispatch to a thread.

  25. Signal Handling in Linux

  26. History about signal handling • unreliable signal: See two classical code: race condition example 1: int sig_int(); /* singal hander */ int main( int argc, char **argv ) { ... signal( SIGINT, sig_int ); /* install my own signal handler */ .... } void sig_int( int signum ) { /* here the kernel sends a signal again, I don’t get it here.. */ signal( SIGINT, sig_int ); /* reinstall the signal handler */ }

  27. History about signal handling Example 2: static volatile sig_atomic_t sig_int_flag; /* set nonzero when signal occurs */ int main( int argc, char **argv ) { int sig_int(); signal( SIGINT, sig_int ); while ( sig_int_flag == 0 ) /* I may lose the signal here  */ pause(); /* waiting for a incoming signal */ ... } void sig_int( int signum ) { signal( SIGINT, sig_int ); sig_int_flag = 1; }

  28. History about signal handling • Reliable signal handling • 1. permanent signal handling • 2. masking to protect the critical area: masked = blocked • 3. atomic unblocked and waiting operation: sigsuspend() • 4. for performance, put signal masks into PCB, so we need not wakeup some process now

  29. Issues about signal handling • Restartable system calls • Waiting for a device operation of slow speed: socket, terminal • errno == EINTR • Reentrant functions • Called by both the main program and signal handler • stdio, malloc/free, routines using global variables • I/O operations with timeout • Use longjmp() & setjmp(), but signal interaction • Use select()/poll() • There is no other good means for this requirements now.

  30. Functions about signal (1) • 1. sending signals • kill( pid_t pid, int sig ): pid, see waitpid() • sigsend( idtype_t, id_t, int ): idtype_t, see waitid() • 2. using signal sets • sigset_t: p6-11 • sigprocmask(): p6-12, 13, operating the process’ blocked mask • Remember: restore the old mask: SIG_SETMASK • Catching signals: p6-15, 16, 17, 18, • void ( *signal( int signum, void (*sighandler)(int) ) )(int); • Using sigaction() is the best choice. • Flag SA_SIGINFO • See the examples sigaction.c: use workshop to evaluate siginfo_t

  31. Functions about signal (2) • Catching SIGCHLD • 1. in the main program, invoke wait()/waitpid() • 2. install a SIGCHLD handler, and in which we should use wait • 3. ignore SIGCHLD • 4. use sigaction() and the flag SA_NOCLDWAIT • 5. fork() and fork(): ask the init process reap my sons

  32. Example - SIGCHLD • void childhandler( int signo ) • { … • saveerrno = errno; • /* get all outstanding terminated children */ • for ( ;; ) • { • pid = waitpid( -1, &status, WNOHANG ); • if ( pid == 0 ) { • /* 1. no dead children, but some live ones */ • break; • } else if ( pid == -1 && errno == ECHILD ) { • /* 2. no more children, dead or running */ • break; • } else if (pid == -1) { • /* should not get this */ • perror("waitpid"); • abort(); • } • /* 3. status contains the reaped status of one child */ • /* If desired, save status for main program. */ • } • errno = saveerrno; • return; • } • // sig_atomic_t

  33. Functions about signal (3) • Using alarm signals • alarm(), Textbook, p167: timeout.c • setitimer() & getitimer(): • setitimer(): itimerval.it-value, current value? • !!!! Read man setitimer carefully, specially used in the multithreaded environment • Notes: • Timer set by setitimer() is permanent. • There is only 4 timers for one process. So we need implement our own software timeout mechanism sometime. • Hint: Data-link timer queue management • sigsetjmp() & siglongjmp() & timeout => timed system call

  34. Functions about signal (4) • Waiting for a signal: • sigpause( int signum ); a particular signal • Used in the synchronization between parent & child processes • sigsuspend( sigset_t *set ); /****** important *******/ • Atomic unblock and waiting: reliable signal • Example: sigprocmask( SIG_BLOCK, &newset, &oldmask ); /* critical region */ if ( condition ) /* may while ( flag ), */ sigsuspend( &set ); sigprocmask( SIG_SETMASK, &oldmask, NULL ); • Remember: during waiting for a signal, and at the same time invoking a system call, no reliable ways now.

  35. Exercise • 1. Notes: • The child process's tms structure is cleared: tms_utime , stime , cutime , and cstime are set to 0 (using times(2)). • The child processes resource utilizations are set to 0. The it_value and it_interval values for the ITIMER_REAL timer are reset to 0. • The set of signals pending for the child process is initialized to the empty set. • Suggestions: • Take into more and more careful consideration: interactions • Use the traditional ways to handle signal • Separate the signal handling/critical region from the remainder

  36. Process Relationship (1)

  37. Process Relationship (3) • History: System V & BSD => Session( job control, login ) • The init process

  38. System and Process Information • Host information: Book, p3-4, • System variables • File and directory limits • Machine time • Converting time • Time usage

More Related