From 4c3d119dfd2fd34eff7f514fa90a7902e7e526a7 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Thu, 21 Aug 2025 11:25:48 -0600 Subject: [PATCH] Turn off watchdog when done in tests If you set a watchdog timer, you should clear it when its no longer needed. Otherwise it can go off, aborting your test script. In these more than two dozen test files, it hasn't mostly been a problem because the script finishes before the timer goes off. But I bet that some heisenbugs have been the result of not clearing it. --- dist/IO/t/io_multihomed.t | 2 ++ dist/IO/t/io_udp.t | 2 ++ dist/threads-shared/t/wait.t | 2 ++ dist/threads-shared/t/waithires.t | 2 ++ dist/threads/t/free.t | 2 ++ dist/threads/t/free2.t | 2 ++ dist/threads/t/libc.t | 2 ++ ext/XS-APItest/t/keyword_plugin_threads.t | 2 ++ ext/re/t/re_funcs_u.t | 3 ++- t/io/closepid.t | 2 ++ t/io/openpid.t | 1 + t/mro/package_aliases.t | 1 + t/mro/package_aliases_utf8.t | 1 + t/op/sigdispatch.t | 2 ++ t/op/signame_canonical.t | 2 ++ t/op/study.t | 2 ++ t/op/threads.t | 1 + t/op/time.t | 2 ++ t/op/time_loop.t | 2 ++ t/op/waitpid.t | 1 + t/perf/speed.t | 2 ++ t/perf/taint.t | 2 ++ t/re/fold_grind.pl | 1 + t/re/pat_psycho.t | 2 ++ t/re/speed.t | 2 ++ t/re/subst.t | 1 + t/win32/popen.t | 2 ++ 27 files changed, 47 insertions(+), 1 deletion(-) diff --git a/dist/IO/t/io_multihomed.t b/dist/IO/t/io_multihomed.t index a63d87306fe6..680a591b8621 100644 --- a/dist/IO/t/io_multihomed.t +++ b/dist/IO/t/io_multihomed.t @@ -117,3 +117,5 @@ if (my $pid = fork()) { } else { die; } + +watchdog(o); diff --git a/dist/IO/t/io_udp.t b/dist/IO/t/io_udp.t index 2adc6a4a6927..2a1d50b3fa53 100644 --- a/dist/IO/t/io_udp.t +++ b/dist/IO/t/io_udp.t @@ -99,6 +99,8 @@ is($buf, 'FOObar'); } } +watchdog(0); + exit(0); # EOF diff --git a/dist/threads-shared/t/wait.t b/dist/threads-shared/t/wait.t index 0f815d6f6614..5c6a5a77cad0 100644 --- a/dist/threads-shared/t/wait.t +++ b/dist/threads-shared/t/wait.t @@ -335,6 +335,8 @@ SYNCH_REFS: { } # -- SYNCH_REFS block +Test::watchdog(0); + # Done exit(0); diff --git a/dist/threads-shared/t/waithires.t b/dist/threads-shared/t/waithires.t index 44c4bf99fad8..e162e182ffa8 100644 --- a/dist/threads-shared/t/waithires.t +++ b/dist/threads-shared/t/waithires.t @@ -368,6 +368,8 @@ SYNCH_REFS: { } # -- SYNCH_REFS block +Test::watchdog(0); + # Done exit(0); diff --git a/dist/threads/t/free.t b/dist/threads/t/free.t index c40fe1823f14..069567b47e1d 100644 --- a/dist/threads/t/free.t +++ b/dist/threads/t/free.t @@ -209,6 +209,8 @@ sub threading_3 { } ok($COUNT == 2, "Done - $COUNT threads"); +Test::watchdog(0); + exit(0); # EOF diff --git a/dist/threads/t/free2.t b/dist/threads/t/free2.t index 8bb5580a9c20..f9d6c1c6a4f9 100644 --- a/dist/threads/t/free2.t +++ b/dist/threads/t/free2.t @@ -333,6 +333,8 @@ TEST_STARTS_HERE: } ok($COUNT == 17, "Done - $COUNT threads"); +Test::watchdog(0); + exit(0); # EOF diff --git a/dist/threads/t/libc.t b/dist/threads/t/libc.t index 592b8d350e40..eb2ebf7fd301 100644 --- a/dist/threads/t/libc.t +++ b/dist/threads/t/libc.t @@ -49,6 +49,8 @@ for (1..$i) { is($threads[$_]->join(), 0, 'localtime() thread-safe'); } +watchdog(0); + exit(0); # EOF diff --git a/ext/XS-APItest/t/keyword_plugin_threads.t b/ext/XS-APItest/t/keyword_plugin_threads.t index db23ce7d58c8..972445b7a89a 100644 --- a/ext/XS-APItest/t/keyword_plugin_threads.t +++ b/ext/XS-APItest/t/keyword_plugin_threads.t @@ -26,6 +26,8 @@ for my $t (1 .. 3) { })->join; } +watchdog(0); + print "all is well\n"; ---- all is well diff --git a/ext/re/t/re_funcs_u.t b/ext/re/t/re_funcs_u.t index 70820df3c398..1a42fe55d5bb 100644 --- a/ext/re/t/re_funcs_u.t +++ b/ext/re/t/re_funcs_u.t @@ -128,7 +128,7 @@ if ('1234'=~/(?:(?\d)|(?!))(?\d)(?\d)(?\d)/){ # New tests go here ^^^ { # Keep these tests last, as whole script will be interrupted if times out - # Bug #72998; this can loop + # Bug #72998; this can loop watchdog(10); eval '"\x{100}\x{FB00}" =~ /\x{100}\N{U+66}+/i'; pass("Didn't loop"); @@ -137,6 +137,7 @@ if ('1234'=~/(?:(?\d)|(?!))(?\d)(?\d)(?\d)/){ no warnings; # Because the 8 may be warned on eval 'qr/\18/'; pass(q"qr/\18/ didn't loop"); + watchdog(0); } done_testing(); diff --git a/t/io/closepid.t b/t/io/closepid.t index c05ef8c12f06..cdc6d256e44a 100644 --- a/t/io/closepid.t +++ b/t/io/closepid.t @@ -42,3 +42,5 @@ SKIP: kill $killsig, $pid; open STDIN, "<&", $savein; } + +watchdog(0); diff --git a/t/io/openpid.t b/t/io/openpid.t index 8b4833a16cfa..5b92ab01de71 100644 --- a/t/io/openpid.t +++ b/t/io/openpid.t @@ -102,3 +102,4 @@ print "# waiting for process $pid4 to exit\n"; $reap_pid = waitpid $pid4, 0; is( $reap_pid, $pid4, 'fourth process reaped' ); +watchdog(0); diff --git a/t/mro/package_aliases.t b/t/mro/package_aliases.t index dd811a62f88f..2b742f5b11f1 100644 --- a/t/mro/package_aliases.t +++ b/t/mro/package_aliases.t @@ -300,6 +300,7 @@ watchdog 3; *foo:: = \%::; *Acme::META::Acme:: = \*Acme::; # indirect self-reference pass("mro_package_moved and self-referential packages"); +watchdog 0; # Deleting a glob whose name does not indicate its location in the symbol # table but which nonetheless *is* in the symbol table. diff --git a/t/mro/package_aliases_utf8.t b/t/mro/package_aliases_utf8.t index 0fc762d2d5c4..8bb97029b4e7 100644 --- a/t/mro/package_aliases_utf8.t +++ b/t/mro/package_aliases_utf8.t @@ -368,6 +368,7 @@ watchdog 3; *ᕘ:: = \%::; *Aᶜme::Mῌ::Aᶜme:: = \*Aᶜme::; # indirect self-reference pass("mro_package_moved and self-referential packages"); +watchdog 0; # Deleting a glob whose name does not indicate its location in the symbol # table but which nonetheless *is* in the symbol table. diff --git a/t/op/sigdispatch.t b/t/op/sigdispatch.t index 242fb8ec5846..30fdb26ae47c 100644 --- a/t/op/sigdispatch.t +++ b/t/op/sigdispatch.t @@ -167,3 +167,5 @@ like $@, qr/No such hook: __DIE__\\0whoops at/; is($int_called, 1); is($@, "died"); } + +watchdog(0); diff --git a/t/op/signame_canonical.t b/t/op/signame_canonical.t index 241b57a5f47f..009817887a34 100644 --- a/t/op/signame_canonical.t +++ b/t/op/signame_canonical.t @@ -73,3 +73,5 @@ foreach my $dupe (@duplicate_signals) { is( $SIG{$canonical_name}, undef, "The signal $canonical_name is cleared after local goes out of scope." ); } +watchdog(0); + diff --git a/t/op/study.t b/t/op/study.t index c84724962f95..8f7b63002396 100644 --- a/t/op/study.t +++ b/t/op/study.t @@ -158,3 +158,5 @@ TODO: { push @got, $_ foreach $a =~ /[^x]d(?{$a .= ''})[^x]d/g; is("@got", 'ydyd ydyd', '#92696 $a .= \'\' inside (?{}), $a studied'); } + +watchdog(0); diff --git a/t/op/threads.t b/t/op/threads.t index 35ddad187274..04f4bcaf3f39 100644 --- a/t/op/threads.t +++ b/t/op/threads.t @@ -149,6 +149,7 @@ watchdog(180, "process"); $_->join for @t; ok(1, '[perl #45053]'); } +watchdog(0); sub matchit { is (ref $_[1], "Regexp"); diff --git a/t/op/time.t b/t/op/time.t index 9fdc7b8cf6ab..d9e06d40dd3b 100644 --- a/t/op/time.t +++ b/t/op/time.t @@ -248,3 +248,5 @@ SKIP: { is scalar gmtime("NaN"), undef, '[perl #123495] gmtime(NaN)'; is scalar localtime("NaN"), undef, 'localtime(NaN)'; } + +watchdog(0); diff --git a/t/op/time_loop.t b/t/op/time_loop.t index 6f4acdc1f952..710b01ee9179 100644 --- a/t/op/time_loop.t +++ b/t/op/time_loop.t @@ -14,3 +14,5 @@ watchdog(2); local $SIG{__WARN__} = sub {}; is gmtime(2**69), undef; is localtime(2**69), undef; + +watchdog(0); diff --git a/t/op/waitpid.t b/t/op/waitpid.t index 497fc26cb688..d3b8806d6390 100644 --- a/t/op/waitpid.t +++ b/t/op/waitpid.t @@ -35,5 +35,6 @@ watchdog(10); pass("didn't block on waitpid(0, ...)"); } +watchdog(0); done_testing(); diff --git a/t/perf/speed.t b/t/perf/speed.t index bab29d441a44..7df4b4e9a96f 100644 --- a/t/perf/speed.t +++ b/t/perf/speed.t @@ -42,4 +42,6 @@ SKIP: { pass("COW 1Mb strings"); } +watchdog(0); + 1; diff --git a/t/perf/taint.t b/t/perf/taint.t index 275611897f58..d69f1746f7a3 100644 --- a/t/perf/taint.t +++ b/t/perf/taint.t @@ -61,4 +61,6 @@ my $taint = substr($ENV{PATH}, 0, 0); # and empty tainted string pass("RT #130584 pos on tainted utf8 string"); } +watchdog(0); + 1; diff --git a/t/re/fold_grind.pl b/t/re/fold_grind.pl index 2922b25dc57c..7e00dfee36b8 100644 --- a/t/re/fold_grind.pl +++ b/t/re/fold_grind.pl @@ -1101,6 +1101,7 @@ (@) } } +watchdog(0); plan($count); 1 diff --git a/t/re/pat_psycho.t b/t/re/pat_psycho.t index 336039521d7c..341a605cfc28 100644 --- a/t/re/pat_psycho.t +++ b/t/re/pat_psycho.t @@ -35,6 +35,8 @@ plan tests => 15; # Update this when adding/deleting tests. run_tests() unless caller; +watchdog(0); + # # Tests start here. # diff --git a/t/re/speed.t b/t/re/speed.t index b61009c3b45f..5ba77f885c17 100644 --- a/t/re/speed.t +++ b/t/re/speed.t @@ -161,6 +161,8 @@ PROG like("!\xdf", eval 'qr/\pp(?aai)\xdf/', 'Compiling qr/\pp(?aai)\xdf/ doesn\'t loop'); + watchdog(0); + } # End of sub run_tests 1; diff --git a/t/re/subst.t b/t/re/subst.t index 6035b260e795..e669ae07a769 100644 --- a/t/re/subst.t +++ b/t/re/subst.t @@ -882,6 +882,7 @@ fresh_perl_is( '$_="abcdefg123456"; s/(?<=...\G)?(\d)/($1)/; print' => 'abcdefg( ::is($fc, 1, '$tied_ref =~ s/non-utf8/utf8/ fetch count'); ::like("$s", qr/^\x{101}AR\(0x.*\)\z/, '$tied_ref =~ s/non-utf8/utf8/ result'); + ::watchdog(0); } # RT #97954 diff --git a/t/win32/popen.t b/t/win32/popen.t index 07ac390a51bb..a0c72a9eceac 100644 --- a/t/win32/popen.t +++ b/t/win32/popen.t @@ -24,4 +24,6 @@ for(1..100) { } PERL +watchdog(0); + done_testing();