Last Updated: 2019-03-11 Mon 11:23

CSCI 4061 Lab07: Basic Signals and Handlers

CODE DISTRIBUTION: lab07-code.zip

  • Download the code distribution every lab
  • See further setup instructions below

CHANGELOG:

1 Rationale

Signals are one of the simplest forms of communication between processes. They are essential for management of running programs and can also be used for other purposes. This lab explores the C function kill() which sends signals and the signal handler setup function signal() which can allow signals to be caught and handled. It assumes basic familiarity with the shell commands kill and pkill which also send signals primarily to terminate misbehaving processes.

1.1 Associated Reading

  • Ch 10 of Stevens/Rago discusses basics of signals and signal handlers.
  • Ch 8.1-8.7 of Robbins/Robbins has similar coverage.

1.2 Grading Policy

  • 10% of lab credit is earned by completing a midterm feedback survey on Canvas
  • 20% of lab credit is earned by showing your lab leader answers during lab
  • 70% of lab credit is earned by submitting required files

See the full policy in the syllabus.

2 Questions about Signals and Handlers

The codepack for the lab contains the following files:

File Description
QUESTIONS.txt Questions to answer
memory_parts.c Problem 1 code to analyze
circle_of_life.c Problem 2 code to analyze
birth_death.c Problem 2 code to analyze
no_interruptions.c File with signal handler for Problem 2
                           __________________

                            LAB 07 QUESTIONS
                           __________________


- Name: (FILL THIS in)
- NetID: (THE kauf0095 IN kauf0095@umn.edu)

Answer the questions below according to the lab specification. Write
your answers directly in this text file and submit it to complete the
lab.


PROBLEM 1: Virtual Memory and pmap
==================================

(A)
~~~

  Examine the source code for the provided `memory_parts.c'
  program. Identify what region of program memory you expect the
  following variables to be allocated into:
  - global_arr[]
  - local_arr[]
  - malloc_arr


(B)
~~~

  Compile the `memory_parts' using the provided Makefile.
  ,----
  | > make memory_parts
  `----
  Run the program and note that it prints several pieces of information
  - The addresses of several of the variables allocated
  - Its Process ID (PID) which is a unique number used to identify the
    running program. This is an integer.
  For example, the output might be
  ,----
  | > ./memory-parts
  | 0x55dc6442c98a : main()
  | 0x55dc6462d0c0 : global_arr
  | 0x7ffc7f3e0310 : local_arr
  | 0x55dc652ad260 : malloc_arr
  | 0x7f53c5280000 : mmap'd file
  | my pid is 11160
  | press any key to continue
  `----
  so the programs PID is 11160

  The program will also stop at this point until a key is pressed. DO
  NOT PRESS A KEY YET.

  Open another terminal and type the following command in that new
  terminal.
  ,----
  | > pmap THE-PID-NUMBER-THAT-WAS-PRINTED-EARLY
  `----

  Paste the output of pmap below.


(C)
~~~

  pmap prints out the virtual address space table for the program. The
  leftmost column is a virtual address mapped by the OS for the program
  to some physical location.  The next column is the size of the area of
  memory associated with that starting address. The 3rd column contains
  permissions of the program has for the memory area: r for read, w for
  read, x for execute. The final column is contains any identifying
  information about the memory area that pmap can discern.

  Compare the addresses of variables and functions from the paused
  program to the output. Try to determine the virtual address space in
  which each variable resides and what region of program memory that
  virtual address must belong to (stack, heap, globals, text).  In some
  cases, the identifying information provided by pmap may make this
  obvious.


(D)
~~~

  The minimum size of any virtual area of memory appears to be 4K. Why
  is this the case?


(E)
~~~

  Notice that in addition to the "normal" variables that are mapped,
  there is also an entry for the mmap()'d file 'gettysburg.txt' in the
  virtual address table.  The mmap() function is explored in the next
  problem but note its calling sequence which involves use of a couple
  system calls:
  1. `open()' which is a low level file opening call which returns a
     numeric file descriptor.
  2. `fstat()' which obtains information such as size for an open file
     based on its numeric file descriptor. The `stat()' system call was
     explored earlier in the class and does the same thing provided the
     name of a file.


PROBLEM 2 `birth_death.c'
=========================

A
~

  Compile `circle_of_life.c' to the program `circle_of_life' and run
  it. Examine the results and feel free to terminate execution
  early. Examine the source code if desired though it is merely a
  print/sleep loop.

  Compile `birth_death.c' to the program `birth_death'. This program is
  invoked with two arguments, another program name and a "lifetime"
  which is an integer number of seconds. Run it like
  ,----
  | $> ./birth_death ./circle_of_life 4
  `----
  and show the output below.


B
~

  Examine the source code for `birth_death.c' and determine the system
  call the parent program (`birth_death') uses to send signals to the
  child program. Paste this line below and explain which signal is being
  sent.


C
~

  `birth_death.c' waits for a child to finish then outputs what signal
  caused it to be terminated if that was the cause of death. Paste the
  lines of code which determine if a child was terminated due to a
  signal below and mention the macros used for this purpose.


D
~

  Compile the program `no_interruptions.c' and run it with
  `birth_death'. Show your results below.

  Note that you may need to send signals to `no_interruptions' to
  forcibly end it. The `pkill' command is useful for this as in
  ,----
  | pkill no_inter        # send TERM signal to proc name matching "no_inter"
  | pkill -KILL no_inter  # send KILL signal to proc name matching "no_inter"
  `----


E
~

  Examine the `no_interruptions.c' code and describe how it is able to
  avoid being killed when receiving the interrupt and TERM signals. Show
  the lines of code used to accomplish this signal handling.

3 What to Understand

Ensure that you understand

  • How to send signals to other process with the kill() function
  • How a process can detect whether a child was signaled and if the signal was terminal
  • How processes can set up simple signal handlers and which signals cannot be handled.

4 What to Turn In

Submit your completed QUESTIONS.txt file to Canvas under the appropriate lab heading. Make sure to paste in any new code you were to write at appropriate locations in the file.


Author: Chris Kauffman (kauffman@umn.edu)
Date: 2019-03-11 Mon 11:23