diff options
author | Yves Orton <demerphq@gmail.com> | 2022-11-29 12:00:31 +0100 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2022-11-30 12:10:04 +0100 |
commit | ce3819cf202a3c5c172fdfaee0412bb5576cf2c7 (patch) | |
tree | 7c94a83b003c4f47bddc1022c37e0d237fd41e06 /ext | |
parent | c9c8e2368deb1a7e6bbeb67711f2706517c0f092 (diff) | |
download | perl-ce3819cf202a3c5c172fdfaee0412bb5576cf2c7.tar.gz |
perl.c - move PL_restartop assert out of perl_run()
In dd66b1d793 we added an assert to perl_run() that PL_restartop should
never be true when perl_run() is called after perl_parse(). Looked at
from the point of the internals, which calls perl_parse() and perl_run()
exactly once, this made sense.
It turns out however that there is at least one XS module out there that
expects to be able to set PL_restartop and then call perl_run(). If that
works out for them then we shouldn't block it, as we aren't really
trying to say "perl_run() should never be called with PL_restartop set"
(at least this assert wasn't trying to say that really), we are trying
to assert "between the top level transition from perl_parse() to
perl_run() we shouldnt leak any PL_restartop".
One could argue the assert maybe should go at the end of perl_parse(),
but I chose to put it in Miniperl.pm and thus into perlmain.c and
miniperlmain.c as I am not certain that perl_parse() should never be
called with PL_restartop set already, and putting it in the main code
really does more closely reflect the intent of this assert anyway.
This was reported as Blead Breaks CPAN Github Issue #20557.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm b/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm index 38a37244e2..18627f8a5e 100644 --- a/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm +++ b/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm @@ -5,7 +5,7 @@ use Exporter 'import'; use ExtUtils::Embed 1.31, qw(xsi_header xsi_protos xsi_body); our @EXPORT = qw(writemain); -our $VERSION = '1.12'; +our $VERSION = '1.13'; # blead will run this with miniperl, hence we can't use autodie or File::Temp my $temp; @@ -135,8 +135,29 @@ main(int argc, char **argv, char **env) PL_perl_destruct_level = 0; } PL_exit_flags |= PERL_EXIT_DESTRUCT_END; - if (!perl_parse(my_perl, xs_init, argc, argv, (char **)NULL)) + if (!perl_parse(my_perl, xs_init, argc, argv, (char **)NULL)) { + + /* perl_parse() may end up starting its own run loops, which + * might end up "leaking" PL_restartop from the parse phase into + * the run phase which then ends up confusing run_body(). This + * leakage shouldn't happen and if it does its a bug. + * + * Note we do not do this assert in perl_run() or perl_parse() + * as there are modules out there which explicitly set + * PL_restartop before calling perl_run() directly from XS code + * (Coro), and it is conceivable PL_restartop could be set prior + * to calling perl_parse() by XS code as well. + * + * What we want to check is that the top level perl_parse(), + * perl_run() pairing does not allow a leaking PL_restartop, as + * that indicates a bug in perl. By putting the assert here we + * can validate that Perl itself is operating correctly without + * risking breakage to XS code under DEBUGGING. - Yves + */ + assert(!PL_restartop); + perl_run(my_perl); + } #ifndef PERL_MICRO /* Unregister our signal handler before destroying my_perl */ |