On Tue, May 08, 2018 at 05:57:10PM +0100, Steve Hay via perl5-porters wrote: > Pre-8e920bd341 outputs this: ... > END: parent: killing (-12584) > > Blead and your branch both output this: > [...] Ctrl+C to kill it Thanks for that, I finally know what's going on. TL;DR: a can of worms has been opened, and for 5.28 we should close the can by reverting for now the 8e920bd341 PERL_EXIT_DESTRUCT_END change (plus the tests), then re-address this issue post 5.28. Long form: As I mentioned earlier in this thread, the main() function on UNIXYy builds looks like PL_exit_flags |= PERL_EXIT_DESTRUCT_END; if (!perl_parse(my_perl...) perl_run(my_perl); exitstatus = perl_destruct(my_perl); Setting the PERL_EXIT_DESTRUCT_END flag moves the calling of END blocks from being handled at the end of perl_run() to being handled at the beginning of perl_destruct(). This means that a premature exit from perl_parse(), such as BEGIN { exit(1) }, doesn't skip calling END blocks. Zefram's 8e920bd341 commit merely set the PERL_EXIT_DESTRUCT_END flag on other platforms such as win32, so that they too would call END blocks even after BEGIN { exit(1) }. However, calling END blocks isn't *quite* the first thing in perl_destruct(); before that it does /* wait for all pseudo-forked children to finish */ PERL_WAIT_FOR_CHILDREN; so by setting PERL_EXIT_DESTRUCT_END, we've moved the calling of END blocks to *after* the reaping of pseudo-forked children. It so happens that of the failing distributions and tests that I looked at, they shared a common idiom: fork() a child to start a test server which can be used to run tests against, then at the end, kill off any such children with END { kill 9, @child_pids } Now on win32, the END block won't get called until after the children have finished, but the children won't finish until the have been killed by the parent calling the END block. Hence deadlock. The fix may well be to move PERL_WAIT_FOR_CHILDREN to after the call_list(PL_endav) in perl_destruct(), but I think messing about like that in late code freeze is asking for trouble, There are also wider issues. For example, one of the short bits of code Steve ran for me earlier showed that the win32 fork() emulation wasn't calling END() blocks in the child. We need to look at all the cases and decide whether and when END blocks should be called, and if so fix them on platforms where they don't match expectations , e.g. BEGIN { die } BEGIN { exit 0 } BEGIN { exit 1 } die exit 0 exit 1 fork; then in child: eval 'BEGIN { die }' fork; then in child: eval 'BEGIN { exit 0 }' fork; then in child: eval 'BEGIN { exit 1 }' fork; then in child: die fork; then in child: exit 0 fork; then in child: exit 1 fork; then from parent, kill child fork; then from parent, kill 9, child -- Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.Thread Previous | Thread Next