https://bugs.gentoo.org/966090 https://savannah.gnu.org/bugs/index.php?67687#comment3 https://file.savannah.gnu.org/file/sv67687_release_tokens.diff?file_id=57804 Rebased on make-4.4.1 because of test changes. commit 04a04b5dfe66de46353c9fe31dd64efab2516257 Author: Dmitry Goncharov Date: Thu Nov 13 00:25:15 2025 -0500 [SV 67687] Release all jobserver tokens upon a fatal signal. * src/commands.c (fatal_error_signal): Call jobserver_clear after reap_childen to let free_child run jobserver_release before the pipe/fifo is closed. * tests/scripts/features/jobserver: Add tests. --- a/src/commands.c +++ b/src/commands.c @@ -531,7 +531,6 @@ fatal_error_signal (int sig) temp_stdin_unlink (); osync_clear (); - jobserver_clear (); /* A termination signal won't be sent to the entire process group, but it means we want to kill the children. */ @@ -577,6 +576,8 @@ fatal_error_signal (int sig) while (job_slots_used > 0) reap_children (1, 1); + jobserver_clear (); + /* Delete any non-precious intermediate files that were made. */ remove_intermediates (1); --- a/tests/scripts/features/jobserver +++ b/tests/scripts/features/jobserver @@ -198,4 +198,39 @@ all:;@echo "$$MAKEFLAGS" run_make_test(q!all:;@echo hi!, "", "#MAKE#: cannot open jobserver nosuchfile: $ERR_no_such_file\n#MAKE#: $j1err\nhi\n"); } +if ($port_type eq 'UNIX') { + # sv 67687. + # Test that make releases all jobserver tokens upon a fatal signal. + # + # When the submake releases all its tokens make prints something like + # + # "make[1]: *** [child.mk:2: a] Terminated + # make[1]: *** [child.mk:2: b] Terminated + # make: *** [t001.mk:2: all] Terminated". + # + # When make detects lost jobserver tokens, make prints something like + # + # "make[1]: *** [child.mk:2: a] Terminated + # make[1]: *** [child.mk:2: b] Terminated + # make: *** [t001.mk:2: all] Terminated + # INTERNAL: exiting with 1 jobserver tokens available; should be 3!". + # + # This test has to fail if the last line is "exiting with ...". + # Anchor \Z ensures that the regex won't match when the "exiting with ..." + # message is present, because the preceding "Terminated" message is + # followed by a new line. + # + # "[\w\d ]*" after "Terminated" is for macos. + create_file('child.mk', +'all: a b c +a b:; @sleep 180 +c:; @sleep 2 && kill -term $$PPID'); + my $re = '/#MAKE#: \*\*\* \[#MAKEFILE#:2: all\] Terminated[\w\d ]*\Z/'; + run_make_test(q! +all:; @$(MAKE) --no-print-directory -f child.mk +!, '-j3', $re, 512); + run_make_test(undef, '--jobserver-style=pipe -j3', $re, 512); + unlink('child.mk') unless $keep; +} + 1; -- 2.51.2