diff options
author | Pádraig Brady <P@draigBrady.com> | 2015-05-01 18:03:37 +0100 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2015-05-11 14:41:17 +0100 |
commit | fe02153e6475ae52f90cfccae1d1ba24baf35f9c (patch) | |
tree | 25006e80ac8a20eeebe3f402f4ceec6de74dc50e | |
parent | 8ee3ca4bb96f61ed5fc12da1d751a29fec6f7979 (diff) | |
download | coreutils-fe02153e6475ae52f90cfccae1d1ba24baf35f9c.tar.xz |
tests: avoid hung processes due to gdb SIGCONT handling
* tests/tail-2/inotify-race.sh: Add a `wait` to ensure that
we reap all background gdb and tail processes. That resulted
in the test hanging intermittently and upon investigation was
due to gdb intermittently failing to terminate the child process
due to receiving a SIGCONT signal. Therefore we avoid using
timeout(1) which sends that signal, and instead rely on tail's
inbuilt --pid monitoring on a background sleep process.
Given this new implementation, the VERY_EXPENSIVE guard was removed.
Related issues with this test hanging were previously discussed at:
https://lists.gnu.org/archive/html/bug-coreutils/2009-12/msg00025.html
-rwxr-xr-x | tests/tail-2/inotify-race.sh | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/tests/tail-2/inotify-race.sh b/tests/tail-2/inotify-race.sh index 2b1655c48..d28f898b6 100755 --- a/tests/tail-2/inotify-race.sh +++ b/tests/tail-2/inotify-race.sh @@ -23,11 +23,6 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ tail -# Don't run this test by default because sometimes it's skipped as noted below. -# Also gdb has a bug in Debian's gdb-6.8-3 at least that causes it to not -# cleanup and exit correctly when it receives a SIGTERM, thus hanging the test. -very_expensive_ - touch file || framework_failure_ touch tail.out || framework_failure_ @@ -37,29 +32,46 @@ case $(cat gdb.out) in *) skip_ "can't run gdb";; esac +# Break on a line rather than a symbol, to cater for inline functions break_src="$abs_top_srcdir/src/tail.c" break_line=$(grep -n ^tail_forever_inotify "$break_src") || framework_failure_ break_line=$(echo "$break_line" | cut -d: -f1) || framework_failure_ + +# Note we get tail to monitor a background sleep process +# rather than using timeout(1), as timeout sends SIGCONT +# signals to its monitored process, and gdb (7.9 at least) +# has _intermittent_ issues with this. +# Sending SIGCONT resulted in either delayed child termination, +# or no child termination resulting in a hung test. +# See https://sourceware.org/bugzilla/show_bug.cgi?id=18364 + +env sleep 10 & sleep=$! + # See if gdb works and # tail_forever_inotify is compiled and run -timeout 10s gdb -nx --batch-silent \ +gdb -nx --batch-silent \ --eval-command="break $break_line" \ - --eval-command='run -f file' \ + --eval-command="run --pid=$sleep -f file" \ --eval-command='quit' \ - tail < /dev/null > gdb.out 2>&1 || skip_ 'breakpoint not hit' + tail < /dev/null > gdb.out 2>&1 + +kill $sleep || skip_ 'breakpoint not hit' +wait $sleep # FIXME: The above is seen to _intermittently_ fail with: # warning: .dynamic section for "/lib/libc.so.6" is not at the expected address # warning: difference appears to be caused by prelink, adjusting expectations compare /dev/null gdb.out || skip_ "can't set breakpoints in tail" +env sleep 10 & sleep=$! + # Run "tail -f file", stopping to append a line just before # inotify initialization, and then continue. Before the fix, # that just-appended line would never be output. -timeout 10s gdb -nx --batch-silent \ +gdb -nx --batch-silent \ --eval-command="break $break_line" \ - --eval-command='run -f file >> tail.out' \ + --eval-command="run --pid=$sleep -f file >> tail.out" \ --eval-command='shell echo never-seen-with-tail-7.5 >> file' \ --eval-command='continue' \ --eval-command='quit' \ @@ -68,6 +80,14 @@ pid=$! tail --pid=$pid -f tail.out | (read; kill $pid) +# gdb has a bug in Debian's gdb-6.8-3 at least that causes it to not +# cleanup and exit correctly when it receives a SIGTERM, but +# killing sleep, should cause the tail process and thus gdb to exit. +kill $sleep +wait $sleep + +wait $pid + compare /dev/null tail.out && fail=1 Exit $fail |