I've adjusted this test, and am about to push it along with Paul's patch. It's better to derive the expected output:
diff --git a/tests/misc/sort-unique-segv b/tests/misc/sort-unique-segv index 0a1d4cb..55a7414 100755 --- a/tests/misc/sort-unique-segv +++ b/tests/misc/sort-unique-segv @@ -39,15 +39,7 @@ zzzzzzzzzzz zzzzzzzzzzzz EOF -cat <<\EOF > exp || fail=1 - -z -zzzzzz -zzzzzzz -zzzzzzzzz -zzzzzzzzzzz -zzzzzzzzzzzz -EOF +sort --parallel=1 -u in > exp || fail=1 sort --parallel=2 -u -S 10b < in > out || fail=1 compare out exp || fail=1 >From 3afda5f0076beca786ecbe90875828eb6988a964 Mon Sep 17 00:00:00 2001 From: Paul Eggert <egg...@cs.ucla.edu> Date: Tue, 30 Nov 2010 22:30:12 +0100 Subject: [PATCH 1/2] sort -u: fix a thread-race pointer corruption bug * src/sort.c (write_unique): Save the entire "struct line", not just a pointer to one. Otherwise, with a multi-thread run, sometimes, with some inputs, fillbuf would would win a race and clobber a "saved->text" pointer in one thread just before it was dereferenced in a comparison in another thread. * NEWS (Bug fixes): Mention it. --- NEWS | 3 +++ src/sort.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 2d3f1f3..79484c1 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ GNU coreutils NEWS -*- outline -*- od now prints floating-point numbers without losing information, and it no longer omits spaces between floating-point columns in some cases. + sort -u with at least two threads could attempt to read through a + corrupted pointer. [bug introduced in coreutils-8.6] + ** New features split accepts the --number option to generate a specific number of files. diff --git a/src/sort.c b/src/sort.c index 7e25f6a..1aa1eb4 100644 --- a/src/sort.c +++ b/src/sort.c @@ -3226,13 +3226,13 @@ queue_pop (struct merge_node_queue *queue) static void write_unique (struct line const *line, FILE *tfp, char const *temp_output) { - static struct line const *saved = NULL; + static struct line saved; if (!unique) write_line (line, tfp, temp_output); - else if (!saved || compare (line, saved)) + else if (!saved.text || compare (line, &saved)) { - saved = line; + saved = *line; write_line (line, tfp, temp_output); } } -- 1.7.3.2.846.gf4b062 >From a5207bb1391cb8e169bc6036eb036bb1a89cde89 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Sun, 28 Nov 2010 12:59:38 +0100 Subject: [PATCH 2/2] tests: add test for parallel sort -u segfault bug * tests/misc/sort-unique-segv: New file. * tests/Makefile.am (TESTS): Add it. --- tests/Makefile.am | 1 + tests/misc/sort-unique-segv | 47 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 0 deletions(-) create mode 100755 tests/misc/sort-unique-segv diff --git a/tests/Makefile.am b/tests/Makefile.am index b3be4df..d52f677 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -239,6 +239,7 @@ TESTS = \ misc/sort-rand \ misc/sort-spinlock-abuse \ misc/sort-unique \ + misc/sort-unique-segv \ misc/sort-version \ misc/split-a \ misc/split-bchunk \ diff --git a/tests/misc/sort-unique-segv b/tests/misc/sort-unique-segv new file mode 100755 index 0000000..55a7414 --- /dev/null +++ b/tests/misc/sort-unique-segv @@ -0,0 +1,47 @@ +#!/bin/sh +# parallel sort with --unique (-u) would segfault + +# Copyright (C) 2010 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${srcdir=.}/init.sh"; path_prepend_ ../src +print_ver_ sort + +test "$(nproc)" = 1 && skip_ "requires a multi-core system" + +cat <<\EOF > in || framework_failure_ + + + + + + + +z +zzzzzz +zzzzzzz +zzzzzzz +zzzzzzz +zzzzzzzzz +zzzzzzzzzzz +zzzzzzzzzzzz +EOF + +sort --parallel=1 -u in > exp || fail=1 + +sort --parallel=2 -u -S 10b < in > out || fail=1 +compare out exp || fail=1 + +Exit $fail -- 1.7.3.2.846.gf4b062