Stopping A Process

From time to time you may want to pause a process’ execution. For an interactive program started on a terminal you can typically do this by typing ^Z (Ctrl-Z) to temporarily suspend the process. But what if the process isn’t running in the foreground? For instance, what if you want to stop a daemon process?

There’s a special Unix signal called SIGSTOP that can be used for this purpose. When this signal is sent to the process, instead of running the process’ SIGSTOP handler the kernel will actually suspend the process. The process will stay in the suspended state until SIGCONT is delivered to it.

From the command line, you can send these signals like this (substituting an actual PID):

kill -STOP PID  # stop the process
kill -CONT PID  # resume the process

One situation where I’ve found this to be useful is testing the behavior of programs when they interact with another program that hangs. For instance, let’s say you’re writing a program that interacts with a database, and you want to know how the program will behave if the database becomes unresponsive. You can set up your program to connect to the database and start doing work, and then deliver SIGSTOP to the database process. When this happens all of the existing connections the application has to the database will still be alive (including any TCP sockets), but the database won’t respond. This is a reasonably facsimile of what happens when the database is under very high load.

Trivia 1: You might be wondering if SIGSTOP is how ^Z works. Actually, on Linux ^Z sends a related (but distinct) signal called SIGTSTP. This also stops the process, but differs from SIGSTOP in that it can be caught. So you can write a program that handles and ignores SIGTSTP, but you can’t write one that ignores SIGSTOP.

Trivia 2: There are only two signals that cannot be caught: SIGSTOP is one, and SIGKILL is the other.