Stop and terminate hang program in Linux

There are two types of hang programs in Linux. The usual hang is in application level and the unusual hang is in kernel level which programmers called crash. We are not going to talk about crash now, perhaps in the future.

Why program hangs?

When you run or open a big database program, or maybe surf the Internet with lynx, one page to another, suddenly it stop responding. You wait for a moment, press an arrow keys, Enter, Esc, Ctrl+C, Ctrl+Z but to no avail, the program just freezes. What? Is the program hang?

Program hang happens in Linux when a process get stuck waiting for something. It could be waiting for a process or resources to be free. What makes a program hang is the process or resource it is waiting is not available or busy.

Some resources take some times to be free. The process is running slowly. The program is not hanged. Hang is real-time problem that one can analyze live the process. Another hang problem is deadlock. This happens when process A is waiting for process B to be free and process B is waiting for process A to be free.

Using Linux ps command

The Linux ps command which means process status is used to display live running processes on the system. What is a process? A process is called daemon in Linux. Every program that is running in the Linux system is a process. More information about ps command can be found in Linux administration - Manage Linux process and daemons tutorial. Let's have some more practice with ps command to solve the Linux hang program.

Login as a normal user. Run this command:

     Welcome to Linux 2.6.27.7-smp (tty1)

     slackware login: bill
     Password:  
     Linux 2.6.27.7-smp
     Last login: Sun Jun 21 11:42:55 +0800 2009 on tty4.  
     No mail.  
     bill@slackware:~$ vim & 
     [1] 551
     bill@slackware:~$ find / *.mpeg 
   

The first command, vim & means we want to run the program in the background. Type the second command. When you press Enter, the result is running quite fast on the screen. Don't worry if you don't like this. Switch to second terminal by pressing Ctrl+Alt+F2. Login as another normal user and su to root. Let's try different ps command's option:

     slackware login: luzar
     Password:  
     Linux 2.6.27.7-smp
     Last login: Sun Jun 21 11:43:16 +0800 2009 on tty4.  
     No mail.  
     luzar@slackware:~$ su - 
     Password: 
     root@slackware:~# ps 
     PID   TTY     TIME        CMD 
     585   tty2   00:00:00     bash 
     619   tty2   00:00:00     ps 
     root@slackware:~# ps -a 
     PID   TTY     TIME        CMD 
     463  tty5    00:00:00     bash 
     551  tty1    00:00:00     vim 
     585  tty2    00:00:00     bash 
     629  tty2    00:00:08     updatedb
     639  tty1    00:00:04     find
     640  tty2    00:00:00     ps
     root@slackware:~# ps au 
     USER     PID   %CPU   %MEM   VSZ    RSS   TTY    STAT   START    TIME   COMMAND
     root     355    0.0   0.3   1392    476   tty3    Ss+   09:14    0:00  /sbin/agetty 384
     root     356    0.0   0.3   1392    476   tty4    Ss+   09:14    0:00  /sbin/agetty 384
     luzar    357    0.0   1.2   2704    1624  tty5    Ss    09:14    0:00  -bash
     root     359    0.0   0.3   1392    476   tty6    Ss+   09:14    0:00  /sbin/agetty 384
     root     463    0.0   1.2   2704    1620  tty5    S+    09:57    0:00  -su
     bill     541    0.0   1.2   2720    1632  tty1    Ss+   10:57    0:00  -bash
     bill     551    0.0   2.3   10560   2952  tty1    T     11:01    0:00  vim
     luzar    575    0.0   1.2   2700    1604  tty2    Ss    11:06    0:00  -bash
     root     585    0.0   1.2   2704    1612  tty2    S     11:06    0:00  -su
     root     629    1.5   0.6   1652    808   tty2    T     11:35    0:08  updatedb
     bill     639    86.8  0.5   1652    692   tty1    D+    11:43    0:06  find / *.mpg
     root     641    0.0   0.6   2408    840   tty2    R+    11:44    0:00  ps au
     root@slackware:~#  

The first command, ps with no option prints out running processes in current terminal. The PID column is the Process ID. The TTY column indicates which terminal the process is running on. The TIME column indicates how much CPU time the process has been running and the CMD column shows the command used.

The second command ps -a, shows more details than ps alone. You can see currently running process in all terminals.

The final command, ps au gives us more details plus some new columns. This time the USER column, %CPU column, %MEM column, VSZ column, RSS column, STAT column and START column added. Maybe you can guess the meaning of some of the new columns here. The important column is the STAT column which shows the status of the process. S stands for sleeping which means the process is waiting for something to happen. Z stands for a zombie process. A zombie process is one whose the parent process has died, leaving the child processes behind. You can stop these zombies processes.

Check out detail information page with info ps command running in the Linux terminal.

Stop hang program with kill command

The commonly used command to stop a process is kill. You are going to use this command a lot in the future, yes, kill the misbehaved program, memory and cpu eating processes, hang programs, etc. Don't worry you're just a process killer ;-)

We just learn how to view running process with ps. We are going to use all the informations above to kill off a process. Let's kill some processes in TTY1.

     root@slackware:~# ps au | grep tty1 
     bill   541    0.0   1.2   2720   1632   tty1   Ss   10:57  0:00  -bash
     bill   551    0.0   2.3   10560  2952   tty1   T    11:01  0:00  vim
     bill   713   69.0   0.5   1652   648    tty1   R+   12:47  0:02  find / *.mpg
     root   715    0.0   0.0   196    28     tty2   R+   12:47  0:00  grep tty1
     root@slackware:~# 

The grep command is used to grab processes from tty1. To kill find process, check it's PID and issue the kill command with the following format:

kill <PID>

     root@slackware:~# kill 713 
     root@slackware:~# ps au | grep tty1 
     bill    541   0.0   1.2   2720   1640  tty1   Ss+  10:57   0:00   -bash
     bill    551   0.0   2.3   10560  2952  tty1   T    11:01   0:00   vim
     root    715   0.0   0.4   1688   596   tty2   S+   12:57   0:00   grep tty1
     root@slackware:~# 

There's no more find process in the list, right?

To force terminate a process, use kill with -9 option.

     root@slackware:~# kill -9 551 
     root@slackware:~# ps au | grep tty1
     bill    541   0.0   1.2   2720   1640  tty1   Ss+   10:57   0:00   -bash
     root    731   0.0   0.4   1688   596   tty2   S+    13:04   0:00   grep tty1
     root@slackware:~#  
   

Switch to terminal 1 and check whether the process is still there:

     /usr/lib/libgdbm.la  
     /usr/lib/libgdbm.so  
     /usr/lib/gdk-pixbuf  
     Terminated 
     bill@slackware:~$ fg  
     -bash: fg: job has terminated  
     [1]+ Killed vim  
     bill@slackware:~$

The program has been terminated. Ok that's good. Now switch back to terminal 2 and issue this command:

     root@slackware:~# killall -9 bash  
 
 
     Welcome to Linux 2.6.27.7-smp (tty2)

     slackware login:

You can use killall instead of kill to terminate all processes. The command killall kills all processes which share the same name. As you can see from the example above, program's name is used instead of pid.

The basic syntax for Linux killall command is:

killall [options] program_name(s)

That's it. Like always, you can find more detail information with man and info commands.