On 02/05/2022 07:03, Paul Eggert wrote:
Thanks for the bug report. This bug is entertaining, as it comes from GCC now being so smart that it optimizes away a memset that cleared padding bits. We added the memset in coreutils 8.14 (2011) to try to fix the sort -g infinite loop bug (introduced in 1999), but the memset isn't guaranteed to fix the bug because the memset can be optimized away.If the padding bits happen to be clear already sort is OK, but if not the results can be inconsistent when you compare two NaNs to each other, and inconsistent results can make sort infloop. The C standard allows this level of intelligence in the compiler, so it's a bug in GNU 'sort'. I installed the attached patch; please give it a try. For now I'll boldly close the bug report; we can easily reopen it if this patch doesn't actually fix the problem.
This is a bit slower of course, but since an edge case not a big concern: $ time yes nan | head -n128095 | timeout 10 sort -g >/dev/null real 0m0.693s $ time yes nan | head -n128095 | timeout 10 src/sort -g >/dev/null real 0m0.924s I'll add the test case I think (attached) since the existing one didn't trigger this. thanks! Pádraig
From bf12c9128523631d7f0ec251734fa05405f70c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com> Date: Mon, 2 May 2022 14:27:34 +0100 Subject: [PATCH] tests: sort-NaN-infloop: augment testing for recent fix * tests/misc/sort-NaN-infloop.sh: Add test case from https://unix.stackexchange.com/a/700967/37127 * src/sort.c: Avoid syntax-check failure. --- src/sort.c | 2 +- tests/misc/sort-NaN-infloop.sh | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sort.c b/src/sort.c index b2a465cf5..8af356c66 100644 --- a/src/sort.c +++ b/src/sort.c @@ -2006,7 +2006,7 @@ numcompare (char const *a, char const *b) static int nan_compare (long double a, long double b) { - char buf[2][sizeof "-nan()" + CHAR_BIT * sizeof a]; + char buf[2][sizeof "-nan""()" + CHAR_BIT * sizeof a]; snprintf (buf[0], sizeof buf[0], "%Lf", a); snprintf (buf[1], sizeof buf[1], "%Lf", b); return strcmp (buf[0], buf[1]); diff --git a/tests/misc/sort-NaN-infloop.sh b/tests/misc/sort-NaN-infloop.sh index 93cf9bd77..3e459884e 100755 --- a/tests/misc/sort-NaN-infloop.sh +++ b/tests/misc/sort-NaN-infloop.sh @@ -23,6 +23,9 @@ echo nan > F || framework_failure_ printf 'nan\nnan\n' > exp || framework_failure_ timeout 10 sort -g -m F F > out || fail=1 +# This was seen to infloop on some systems until coreutils v9.2 (bug 55212) +yes nan | head -n128095 | timeout 10 sort -g > /dev/null || fail=1 + compare exp out || fail=1 Exit $fail -- 2.26.2