coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] tests: avoid hung processes due to gdb SIGCONT handling


From: Pádraig Brady
Subject: [PATCH] tests: avoid hung processes due to gdb SIGCONT handling
Date: Fri, 1 May 2015 18:29:02 +0100

* 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
---
 tests/tail-2/inotify-race.sh | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/tests/tail-2/inotify-race.sh b/tests/tail-2/inotify-race.sh
index 2b1655c..6f1c681 100755
--- a/tests/tail-2/inotify-race.sh
+++ b/tests/tail-2/inotify-race.sh
@@ -23,10 +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 +33,45 @@ 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
+
+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'
 
 # 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"
 
+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,13 @@ 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 $pid
+
 compare /dev/null tail.out && fail=1
 
 Exit $fail
-- 
2.3.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]