Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu'
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL
-DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib -Wdate-time
-D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/build/bash-u3hlEB/bash-4.4.18=.
-fstack-protector-strong -Wformat -Werror=format-security -Wall
-Wno-parentheses -Wno-format-security
uname output: Linux thomas 4.18.0-7-generic #8-Ubuntu SMP Tue Aug 28 18:22:50
UTC 2018 i686 i686 i686 GNU/Linux
Machine Type: i686-pc-linux-gnu
Bash Version: 4.4
Patch Level: 19
Release Status: release
Description:
I was trying to work around the problem of bash not being able to
cancel the read builtin command when a signal comes in and I stumbled
upon this (perhaps unrelated) bug. I'm not sure exactly what's going
on but I have a simple script that demonstrates the problem.
Repeat-By:
Run the following script. Quickly hit a key, then wait to be prompted
to hit Control C. When you hit Control C, the process should stop
responding and your CPU usage should go to 100%. The HUP, TERM and
QUIT signals are ignored.
- 8< - 8< - 8< - CUT HERE - 8< - 8< - 8< -
#!/bin/bash
trap cleanup EXIT
cleanup() {
echo "Huh. There was supposed to be an earth-shattering kaboom."
echo "The bug wasn't triggered. Did you hit the first key quickly?"
echo "Or, perhaps Bash $BASH_VERSION isn't buggy?"
echo "This test was designed for Bash 4.4.19(1) on Ubuntu Cosmic
Cuttlefish."
}
trap huphandler SIGHUP
huphandler() {
# This handler doesn't actually do anything.
# The important thing is that HUP interrupts the wait.
return
}
# Send a SIGHUP to ourselves to interrupt the wait and start "read".
(sleep 2; kill -1 $$; sleep 2; echo -e "\nB: Now try ^C and see what breaks.")
&
echo "A: Quickly press a key before part B! "
while true; do
wait
read -p "Kaboom? " -n1
echo
done
- 8< - 8< - 8< - CUT HERE - 8< - 8< - 8< -
I tried attaching to the process with GDB. The backtrace showed it
being in jobs.c:wait_sigint_handler() or zread.c:zread(). This may be
a red herring, but there is a comment in zread.c with an XXX and a
question that may be worth investigating:
60check_signals_and_traps (); /* XXX - should it be
check_signals()? */
Here is a more extensive log of what gdb said:
$ gdb -p 27088
Attaching to process 27088
Reading symbols from /src/bash-4.4.18/bash...done.
Reading symbols from /lib/i386-linux-gnu/libtinfo.so.6...(no debugging symbols
found)...done.
Reading symbols from /lib/i386-linux-gnu/libdl.so.2...Reading symbols from
/usr/lib/debug//lib/i386-linux-gnu/libdl-2.28.so...done.
done.
Reading symbols from /lib/i386-linux-gnu/libc.so.6...Reading symbols from
/usr/lib/debug//lib/i386-linux-gnu/libc-2.28.so...done.
done.
Reading symbols from /lib/ld-linux.so.2...Reading symbols from
/usr/lib/debug//lib/i386-linux-gnu/ld-2.28.so...done.
done.
wait_sigint_handler (sig=2) at jobs.c:2476
2476 if (interrupt_immediately ||
(gdb) list
2471wait_sigint_handler (sig)
2472 int sig;
2473{
2474 SigHandler *sigint_handler;
2475
2476 if (interrupt_immediately ||
2477 (this_shell_builtin && this_shell_builtin == wait_builtin))
2478{
2479 last_command_exit_value = 128+SIGINT;
2480 restore_sigint_handler ();
2481 /* If we got a SIGINT while in `wait', and SIGINT is trapped, do
2482 what POSIX.2 says (see builtins/wait.def for more info). */
2483 if (this_shell_builtin && this_shell_builtin == wait_builtin &&
2484 signal_is_trapped (SIGINT) &&
2485 ((sigint_handler = trap_to_sighandler (SIGINT)) ==
trap_handler))
2486{
2487 trap_handler (SIGINT);/* set pending_traps[SIGINT] */
2488 wait_signal_received = SIGINT;
2489 if (interrupt_immediately && wait_intr_flag)
2490{
(gdb) bt
#0 wait_sigint_handler (sig=2) at jobs.c:2476
#1
#2 0xb7f09d41 in __kernel_vsyscall ()
#3 0xb7dbc5a7 in __GI___libc_read (fd=0, buf=0xbf956a56, nbytes=1)
at ../sysdeps/unix/sysv/linux/read.c:26
#4 0x0052dce1 in read (__nbytes=1, __buf=0xbf956a56, __fd=0)
at /usr/include/i386-linux-gnu/bits/unistd.h:44
#5 zread (fd=0, buf=0xbf956a56 "V", len=1) at zread.c:56
#6 0x00519c23 in read_builtin (list=0x0) at ./read.def:585
#7 0x004bacc0 in execute_builtin (
builtin=builtin@entry=0x519360 , flags=flags@entry=0,
subshell=0, words=) at execute_cmd.c:4535
#8 0x004bd75a in execute_builtin_or_function (flags=,
fds_to_close=, redirects=, var=0x0,
builtin=0x519360 , words=0x13367c8) at execute_cmd.c:5028
#9 execute_simple_command (simple_command=,
pipe_in=,