Working With Processes and Signals
Goal
You send signals to processes to see how stopping, terminating, and force-killing each differ, and you create a zombie yourself to see how one comes about.
Why it matters
A report that "the process won't die" lumps together at least four different situations. The application may have caught SIGTERM and ignored it, it may be in the D state so that signal handling itself was postponed, or it may already be dead and left behind as a zombie. The responses are all different, so you should first ask at which layer it stopped. And the rule that only SIGKILL and SIGSTOP cannot be caught is the last resort the kernel leaves to the operator; that is why SIGKILL gives no chance to clean up and, for a DB or a queue consumer, is the same as pulling the plug.
Steps
- Start
sleep 3600in the background and write its PID to/root/proc/pid.txt. - Write that process's parent PID to
/root/proc/ppid.txt. - Start another
sleepand stop it (SIGSTOP), then write its PID to/root/proc/stopped_pid.txtand the single state letter after stopping to/root/proc/state_stopped.txt. - Start another
sleep, write its PID to/root/proc/killed_pid.txt, and then terminate it with SIGTERM. - Create
/root/proc/trapper.sh. When it receives SIGTERM, it must add one line to/root/proc/term.log:caught SIGTERM. Make it executable, start it in the background, send it SIGTERM, and check that the log accumulates. - Start
trapper.shagain and this time send SIGKILL. Write the number of lines interm.logjust before sending to/root/proc/before_kill.txtand the number of lines just after sending to/root/proc/after_kill.txt. When the lab ends, notrapper.shmay be left alive. - Spawn one child and have that child finish first, while keeping the parent alive without calling
wait. Write that parent's PID to/root/proc/zombie_parent.txt. - Create
/root/proc/cleanup.sh <패턴>(pattern). It must terminate every process whose command line matches the pattern and print the number of terminated processes as one line in the formterminated=<n>. It must neither count nor kill itself.
Notes
- With
awk '{print $3}' /proc/<PID>/statyou can see the state letter. R running, S sleeping, D uninterruptible sleep, T stopped, Z zombie. kill -0 <PID>sends no signal and only checks existence and permission. It is the standard way to poll for liveness.- Common mistake 1: in step 3, if you confuse terminate (TERM) with stop (STOP), the process disappears and grading fails.
- Common mistake 2: in step 8,
pgrep -falso matches its own command line. If you do not exclude your own PID, the script kills itself.
Start a background process
Start sleep 3600 in the background and write its PID to /root/proc/pid.txt.
Put & after the command to send it to the background. Right after that, $! holds its PID.
Find the parent PID
Write that process's parent PID to /root/proc/ppid.txt.
Look at the PPid line of /proc//status, or use ps -o ppid= -p .
Stop a process
Start another sleep and stop it (SIGSTOP), then write its PID to /root/proc/stopped_pid.txt and the single state letter after stopping to /root/proc/state_stopped.txt.
Stopping and terminating are different. A stopped process stays in the list and its state letter changes.
Politely ask a process to terminate
Start another sleep, write its PID to /root/proc/killed_pid.txt, and then terminate it with SIGTERM.
kill sends SIGTERM by default. Write the PID to the file before you send it.
A script that catches SIGTERM
Create /root/proc/trapper.sh. When it receives SIGTERM, it must add one line to /root/proc/term.log: caught SIGTERM. Make it executable, start it in the background, send it SIGTERM, and check that the log accumulates.
Set the handler in the form trap 'command' TERM. The script must not exit and must stay alive to receive the signal.
SIGKILL cannot be caught
Start trapper.sh again and this time send SIGKILL. Write the number of lines in term.log just before sending to /root/proc/before_kill.txt and the number of lines just after sending to /root/proc/after_kill.txt. When the lab ends, no trapper.sh may be left alive.
Send 9 to the script that has the trap set, and record the line count before and after to compare whether it grew.
Try creating a zombie
Spawn one child and have that child finish first, while keeping the parent alive without calling wait. Write that parent's PID to /root/proc/zombie_parent.txt.
If the child finishes first and the parent stays alive without calling wait, the child becomes a zombie. The parent must keep running.
A pattern-based cleanup script
Create /root/proc/cleanup.sh <패턴> (pattern). It must terminate every process whose command line matches the pattern and print the number of terminated processes as one line in the form terminated=<n>. It must neither count nor kill itself.
Count first with pgrep -f, and exclude your own process. After terminating, print the count in the form terminated=.