Having trouble serializing test with Automake parallel test harness

"G. Branden Robinson" <[email protected]> Thu, 5 Mar 2026 09:58:03 -0600
Newsgroups gmane.comp.printing.groff.general,gmane.comp.sysutils.automake.general
Message-ID <20260305155803.n4xcyag7vcw4qauh@illithid>
Hello Automake mavens,

Please see the attached Git commit.

I had to use a nasty hack to force serialization of two regression tests
that both can cause core dumps, and so can race with each other in the
TOCTTOU window on the existence of a "core" file.

Am I doing something wrong?  Is this a known bug?

Is there something I can do that's (1) portable and (2) less nasty than
sleeping?

Regards,
Branden
dc.diff (text/x-diff, 4.7 KB)
commit a9f9eb958fec96c0530771a9b9bca2f2e7597e66
Author: G. Branden Robinson <[email protected]>
Date:   Thu Mar 5 09:15:30 2026 -0600

    [groff]: Regression-test Savannah #67978.
    
    * src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh:
      Do it.
    
    * src/roff/groff/groff.am (groff_TESTS): Run test.
    
    Test fails at this commit.

diff --git a/ChangeLog b/ChangeLog
index 5edc379be..4d1fea94e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2026-03-05  G. Branden Robinson <[email protected]>
+
+	[groff]: Regression-test Savannah #67978.
+
+	* src/roff/groff/tests/\
+	do-not-crash-on-backslash-X-if-font-invalid.sh: Do it.
+	* src/roff/groff/groff.am (groff_TESTS): Run test.
+
 2026-03-03  Rocket Ma <[email protected]>
 
 	* src/preproc/eqn/eqn.am (neqn): `-f $(SH_DEPS_SED_SCRIPT)`
diff --git a/src/roff/groff/groff.am b/src/roff/groff/groff.am
index 88d95f23c..448d8d89e 100644
--- a/src/roff/groff/groff.am
+++ b/src/roff/groff/groff.am
@@ -64,6 +64,7 @@ groff_TESTS = \
   src/roff/groff/tests/device-request-passes-most-escape-sequences.sh \
   src/roff/groff/tests/device-request-works.sh \
   src/roff/groff/tests/devicem-request-works.sh \
+  src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh \
   src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh \
   src/roff/groff/tests/do-not-free-file-name-pointers-early.sh \
   src/roff/groff/tests/do-not-loop-infinitely-when-breaking-cjk.sh \
@@ -133,6 +134,14 @@ groff_TESTS = \
 TESTS += $(groff_TESTS)
 EXTRA_DIST += $(groff_TESTS)
 
+# This dependency forces serialization of their corresponding tests:
+# since both can create a "core" file, they can race with each other,
+# causing one to spuriously report failure.
+#
+# See section "Parallel Test Harness" of the GNU Automake manual.
+src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.log: \
+  src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.log
+
 # required test artifacts
 EXTRA_DIST += \
   src/roff/groff/tests/artifacts/HONEYPOT \
diff --git a/src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh b/src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh
new file mode 100755
index 000000000..5ed9b99b7
--- /dev/null
+++ b/src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Copyright 2025 G. Branden Robinson
+#
+# This file is part of groff, the GNU roff typesetting system.
+#
+# groff is free software; you can redistribute it and/or modify it over
+# 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.
+#
+# groff 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/>.
+
+groff="${abs_top_builddir:-.}/test-groff"
+
+# troff should not perform invalid memory access when writing a device
+# extension command with `\X` when the current font is invalid.
+# Savannah #67978.
+
+if [ -e core ]
+then
+  echo "$0: 'core' file already exists; skipping" >&2
+  exit 77 # skip
+fi
+
+# We disable filling only to make the crash happen "early", before
+# exiting the formatter because the last input line has been read.
+input='.
+.nr BarPos \n[.fp]
+.sty \n[.fp] Bar
+.fam Foo
+.ft \n[BarPos]
+.tm .f=\n[.f]
+.nf
+\X@baz@
+.'
+
+output=$(printf '%s\n' "$input" | "$groff" -a)
+! test -e core
+
+# vim:set autoindent expandtab shiftwidth=4 tabstop=4 textwidth=72:
diff --git a/src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh b/src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh
index 06f8e1557..753464cea 100755
--- a/src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh
+++ b/src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh
@@ -16,13 +16,17 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
 
 groff="${abs_top_builddir:-.}/test-groff"
 
 # troff should not perform invalid memory access when using `box` to
 # close a regular diversion.  Savannah #67139.
 
+# XXX: We _tried_ to serialize this test with another core dump
+# producer--see "groff.am"--but it doesn't work with Automake 1.16.3.
+# Force serialization the nasty way (and not necessarily reliably).
+sleep 5
+
 if [ -e core ]
 then
   echo "$0: 'core' file already exists; skipping" >&2
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEh3PWHWjjDgcrENwa0Z6cfXEmbc4FAmmpqAIACgkQ0Z6cfXEm
bc5NRRAAhY5JS5jWn0qtvTu0dLnOdLFj+Y92PvLSOFZa9Ulk8nCdjdi499J+11bv
oBBFLena1l67jQT0LE6cdM3FTSN3iPDhNMtFtfqFRpCqFTjxkLZt6G7CaF2S9YZO
XkWzCqEnD/Y6tlrj6ADtLdVisX+A78/dNOpEytkBeOm++fme30ohXQAENhL9KF/d
ngosx8pd0FmRWfvd8Mmco2WjRcL8o6PlOjMUVGJLLxi/mOypJzzOnUtqq1gn3L/4
3rwEM0bKhZzeRavWMBS3Pb6qnEwlDVYWAug4AK59sB3j7PDfZONQOUufuI/pRrWM
HvYuTM2TCzbsdnKYjrfrhj2B6t6BrriuGBnaj06KFcrsCKVWhJfMfcgPZJ1MBf1U
J9sQgenp9RfXAyXdyB8uHlwOkW8p8ukZ7Z0xhQ24CpklShiQ0ql6y2aLwLvhUllT
SlMH+OSWM2Fxu0w33TLoVhQEAXFZtGqbrg7LMftfFgnG0yjxrnYkV7IxRKrw70gE
C+DjBPHrtZAUfBdeacnQzQDgSbmctED4LylQHFbFdY0lMlXtkMVfWKBtPHodTN3g
sVb5z1OZnK4deXXcq0CQGk3fOmgejrUK9aqUFhp4JP8SKcj7EqfwJESJK2qKcHW8
/W4285FoGQhfbcELrozUNcmVTZFfu8B6RO7gUd8O4E+MZnZ2ecI=
=Fz2r
-----END PGP SIGNATURE-----