On 07/01/2026 18:23, Bruno Haible via GNU coreutils General Discussion wrote:
The CI reports a unit test failure of tests/tail/overlay-headers on macOS 26 on 2026-01-05 but not in the previous run on 2025-12-29. The failure could be spurious.Here's the log: FAIL: tests/tail/overlay-headers ================================
+ test 17 = 13 + fail=1
There are multiple issues with this test: 1. It inadvertently left ---disable-inotify in place so wasn't actually testing the problematic code 2. cleanup_() didn't send SIGCONT to tail, which could have resulted in a hung test upon termination 3. We assume tail was in stopped state after kill -STOP returns. We should check this is the case as it can happen async. Probably unlikely, but simple enough to use our exponential backoff helper here to check. 4. tail(1) is never actually stopped in the test! Rather timeout(1) is the process that gets the SIGSTOP since: https://lists.gnu.org/archive/html/coreutils/2025-09/msg00096.html BTW the hang in the above report looks to be due to SIGCONT not resuming the tail(1) process, thus leading to the potential hang I noticed at 2. So the test was never valid, and became worse over time :/ Hopefully the attached addresses these issues. p.s. timeout(1) probably should propagate all signals. something to look at...
From 3c76fc5f396f0a408c6f2c51e1e3a845def1f592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]> Date: Wed, 7 Jan 2026 20:29:54 +0000 Subject: [PATCH] tests: tail/overlay-headers.sh: fix various issues * tests/tail/overlay-headers.sh (cleanup_): Ensure we send SIGCONT to the tail process, otherwise we would hang if the test is terminated while the tail process is in stopped state. (wait4stopped_): A new function to ensure tail is in the stopped state before we start writing to the monitored files. Also remove "---disable-inotify" from $fastpoll so we actually test the inotify code (where supported). Also remove the timeout(1) wrapper, so we actually suspend tail(1). Reported by Bruno Haible on macOS 26 --- tests/tail/overlay-headers.sh | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/tail/overlay-headers.sh b/tests/tail/overlay-headers.sh index ea105379f..a37f6ec5c 100755 --- a/tests/tail/overlay-headers.sh +++ b/tests/tail/overlay-headers.sh @@ -38,11 +38,12 @@ wait4lines_ () } # Speedup the non inotify case -fastpoll='---dis -s.1 --max-unchanged-stats=1' +fastpoll='-s.1 --max-unchanged-stats=1' # Terminate any background tail process cleanup_() { - kill $pid 2>/dev/null && wait $pid; + kill -CONT $pid 2>/dev/null + kill $pid 2>/dev/null && wait $pid kill $sleep 2>/dev/null && wait $sleep } @@ -52,16 +53,32 @@ echo start > file2 || framework_failure_ # Use this as a way to gracefully terminate tail env sleep 60 & sleep=$! -timeout 60 tail $fastpoll --pid=$sleep -f file1 file2 > out & pid=$! +# Note don't use timeout(1) here as it currently +# does not propagate SIGCONT +tail $fastpoll --pid=$sleep -f file1 file2 > out & pid=$! +# Ensure tail is running kill -0 $pid || fail=1 +# Ensure SIGCONT is supported +kill -CONT $pid || framework_failure_ + # Wait for 5 initial lines retry_delay_ wait4lines_ .1 6 5 || fail=1 # Suspend tail so single read() caters for multiple inotify events kill -STOP $pid || fail=1 +wait4stopped_() { + local delay=$1 + case $(ps -o state= -p "$pid" 2>/dev/null) in + T*) return 0 ;; + *) sleep $delay; return 1 ;; + esac +} + +retry_delay_ wait4stopped_ .1 6 || skip_ 'failed to stop tail' + # Interleave writes to files to generate overlapping inotify events echo line >> file1 || framework_failure_ echo line >> file2 || framework_failure_ @@ -76,6 +93,6 @@ retry_delay_ wait4lines_ .1 6 13 || fail=1 kill $sleep && wait || framework_failure_ -test "$(countlines_)" = 13 || fail=1 +test "$(countlines_)" = 13 || { cat out; fail=1; } Exit $fail -- 2.52.0
