bash script hangs when a command is executed in a trap handler

Solution Verified - Updated -

Environment

  • Red Hat Enterprise Linux (RHEL) 5.9

    • bash-3.2-32.el5
  • Red Hat Enterprise Linux (RHEL) 6.4

    • bash-4.1.2-14.el6

Issue

  • A hang on a bash script on RHEL5.7.
  • Issue on handling child processes, if a non-builtin command is executed in a trap handler.

Resolution

  • RHEL 5
    Fixed version: bash-3.2-32.el5_9.1
    For details, please refer to RHBA-2013:1040-1.
* When a trap handler was invoked while running another trap handler, which was
invoked during a pipeline call, bash was unresponsive. With this update,
pipeline calls are saved and subsequently restored in this scenario, and bash
responds normally. (BZ#978840)
  • RHEL 6
    Fixed version: bash-4.1.2-15.el6_4
    For the detail, please refer to RHBA-2013:1096-1.
* When a trap handler was invoked while running another trap handler, which was
invoked during a pipeline call, bash was unresponsive. With this update,
pipeline calls are saved and subsequently restored in this scenario, and bash
responds normally. (BZ#982610)

Root Cause

Bug in bash trap handler.

Diagnostic Steps

How to reproduce the issue:
- It depends on timing of signal interrupts, but it usually takes only a few seconds when performing the following reproducing steps.

Create the following 2 scripts and provide the executable permission to both:

  • running.sh
    ~~~
    #!/bin/bash

    pid_file='/tmp/00825013.pid'
    trap "date; /bin/echo trapped $PID" TERM
    
    PID=$(bash -c 'echo $PPID')
    echo PID: [$PID]
    echo $PID > $pid_file
    
    echo start killing.sh
    ./killing.sh &
    while :; do sleep 1; [ -f $pid_file ] || break; done
    
    while :; do
      cat /proc/uptime
      dd if=/dev/zero bs=1k count=128  2>&1 | cat > /dev/null
    done
    ~~~
    
  • killing.sh
    ~~~
    #!/bin/bash

    pid_file='/tmp/00825013.pid'
    
    PID=$(cat $pid_file)
    rm -f $pid_file
    
    sleep 1.5
    while :; do 
      kill -TERM $PID || break
      usleep 100000
    done
    ~~~
    

Run running.sh. Result (the bash script hangs in a trap handler):
~~~
# ./running.sh
PID: [11524]
start killing.sh
11223.41 10076.46
11223.41 10076.46

11223.91 10076.46
11223.91 10076.46
Tue Apr 30 14:44:46 JST 2013 <- expected trapping
trapped <- expected trapping
11223.91 10076.46
11223.92 10076.46

11224.42 10076.46
11224.42 10076.46
Tue Apr 30 14:44:47 JST 2013
(hangup occurred) <- actual result
~~~

After updating bash according to the Resolution part of this document, hangup doesn't occur and trap processing can continue.

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.