-
Notifications
You must be signed in to change notification settings - Fork 577
panic: restartop in perl_run
#19680
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
On 5/1/22 09:35, AnFunctionArray wrote:
Module: perl
*Description*
Basically sometimes when I run my program I get |panic: restartop in
perl_run| (1 in 5).
*Steps to Reproduce*
Run like 10 times (fast).
*Expected behavior*
Not panic.
*Perl configuration*
|Summary of my perl5 (revision 5 version 35 subversion 12)
configuration: Commit id: 99db5f9
Have you observed this problem with production releases of perl (e.g.,
perl-5.34.1)?
|
At least at first glance,
|
I found it: Try:
|
panic: restartop in perl_run
panic: restartop in perl_run
Confirmed with blead:
Until some point between 5.22 and 5.30 it also then went on to assert in debugging builds:
At 5.18 it doesn't complain; I'll try bisecting on that, but my first guess is that a change in 5.20 just exposed an even older bug. It seems remotely possible this could be related to #19390, where we get a SEGV from:
|
@hvds, is it relevant that something different happens with a couple of spaces in the mix? (i.e. is there a parsing bug?)
|
With the spaces, it stops being an embedded code block.
|
Ah, I hadn't noticed that it would be an error, that suggests it's much more likely to be related to #19390. |
Thanks. I've never used re code blocks and wasn't sure whether whitespacing was allowed or not. |
Manual bisect points to 1022336 as the point we first see the problem (strange, since the immediately preceding commit cdec98f looks more likely to be relevant; however reverting that one in blead doesn't fix the problem). Unfortunately, simply reverting the main element of that commit as below causes miniperl to hang both in @iabyn does anything spring to mind?
|
On Tue, May 03, 2022 at 08:22:32AM -0700, Hugo van der Sanden wrote:
Confirmed with blead:
```
% ./miniperl -e '"test" =~ m{(?{eval {exists $test[-1]{test}}})}'
panic: restartop in perl_run
%
It reduces further to
p -e'"test" =~ m{(?{eval {die "boo!"}})}'
(the $test[-1] was croaking about a non-modifiable array.)
The bug was probably introduced by (or at least the ground prepared by)
my jumbo re_eval patch that went into 5.18.0 and has probably been
sensitive to the exact circumstances of a corrupted context stack ever
since.
I'm currently looking into it further.
…--
The Enterprise successfully ferries an alien VIP from one place to another
without serious incident.
-- Things That Never Happen in "Star Trek" #7
|
GH #19680 Normally in code like eval {.... }; then even if the eval is the last statement in the file or sub, the OP_LEAVETRY isn't the last op in the execution path: it's followed by an OP_LEAVE or OP_LEAVESUB or whatever, which will be the op to resume execution from after an exception is caught. However, if the eval is the *last* thing within a regex code block: /(?{ ...; eval {....}; })/ then the op_next pointer of the OP_LEAVETRY op is actually NULL. This confused S_docatch(), which wrongly assumed that a NULL PL_restartop indicated that the caught exception should be rethrown, popping execution back to the outer perl_run() call and hence leading to the confused panic warning: "panic: restartop in perl_run" The fix is to to separate out the "do we need to re-throw" test, (PL_restartjmpenv != PL_top_env), from the "no more ops so no need to re-enter the runops loop" test, (!PL_restartop).
On Wed, May 04, 2022 at 06:46:30AM -0700, iabyn wrote:
On Tue, May 03, 2022 at 08:22:32AM -0700, Hugo van der Sanden wrote:
> Confirmed with blead:
> ```
> % ./miniperl -e '"test" =~ m{(?{eval {exists $test[-1]{test}}})}'
> panic: restartop in perl_run
> %
It reduces further to
p -e'"test" =~ m{(?{eval {die "boo!"}})}'
(the $test[-1] was croaking about a non-modifiable array.)
The bug was probably introduced by (or at least the ground prepared by)
my jumbo re_eval patch that went into 5.18.0 and has probably been
sensitive to the exact circumstances of a corrupted context stack ever
since.
I'm currently looking into it further.
I now have a fix for this as the first commit in PR #19778.
…--
That he said that that that that is is is debatable, is debatable.
|
GH #19680 Normally in code like eval {.... }; then even if the eval is the last statement in the file or sub, the OP_LEAVETRY isn't the last op in the execution path: it's followed by an OP_LEAVE or OP_LEAVESUB or whatever, which will be the op to resume execution from after an exception is caught. However, if the eval is the *last* thing within a regex code block: /(?{ ...; eval {....}; })/ then the op_next pointer of the OP_LEAVETRY op is actually NULL. This confused S_docatch(), which wrongly assumed that a NULL PL_restartop indicated that the caught exception should be rethrown, popping execution back to the outer perl_run() call and hence leading to the confused panic warning: "panic: restartop in perl_run" The fix is to to separate out the "do we need to re-throw" test, (PL_restartjmpenv != PL_top_env), from the "no more ops so no need to re-enter the runops loop" test, (!PL_restartop).
Fix "panic: restartop in perl_run" (Issue #19680), Then do tweaks and doc improvements to perl's internal exception handling.
GH #19390 This issue is similar to GH #19680 (fixed by v5.37.0-272-g5fd637ce8c), but exiting the eval via a syntax error rather than via raising an exception. In this case, the NULL op_next of the OP_ENTEREVAL was passed to a new RUNOPS loop, which would normally SEGV (or on debugging builds, warn "NULL OP IN RUN").
GH Perl#19680 Normally in code like eval {.... }; then even if the eval is the last statement in the file or sub, the OP_LEAVETRY isn't the last op in the execution path: it's followed by an OP_LEAVE or OP_LEAVESUB or whatever, which will be the op to resume execution from after an exception is caught. However, if the eval is the *last* thing within a regex code block: /(?{ ...; eval {....}; })/ then the op_next pointer of the OP_LEAVETRY op is actually NULL. This confused S_docatch(), which wrongly assumed that a NULL PL_restartop indicated that the caught exception should be rethrown, popping execution back to the outer perl_run() call and hence leading to the confused panic warning: "panic: restartop in perl_run" The fix is to to separate out the "do we need to re-throw" test, (PL_restartjmpenv != PL_top_env), from the "no more ops so no need to re-enter the runops loop" test, (!PL_restartop).
GH Perl#19390 This issue is similar to GH Perl#19680 (fixed by v5.37.0-272-g5fd637ce8c), but exiting the eval via a syntax error rather than via raising an exception. In this case, the NULL op_next of the OP_ENTEREVAL was passed to a new RUNOPS loop, which would normally SEGV (or on debugging builds, warn "NULL OP IN RUN").
GH #19680 Normally in code like eval {.... }; then even if the eval is the last statement in the file or sub, the OP_LEAVETRY isn't the last op in the execution path: it's followed by an OP_LEAVE or OP_LEAVESUB or whatever, which will be the op to resume execution from after an exception is caught. However, if the eval is the *last* thing within a regex code block: /(?{ ...; eval {....}; })/ then the op_next pointer of the OP_LEAVETRY op is actually NULL. This confused S_docatch(), which wrongly assumed that a NULL PL_restartop indicated that the caught exception should be rethrown, popping execution back to the outer perl_run() call and hence leading to the confused panic warning: "panic: restartop in perl_run" The fix is to to separate out the "do we need to re-throw" test, (PL_restartjmpenv != PL_top_env), from the "no more ops so no need to re-enter the runops loop" test, (!PL_restartop). (cherry picked from commit 5fd637c)
GH #19390 This issue is similar to GH #19680 (fixed by v5.37.0-272-g5fd637ce8c), but exiting the eval via a syntax error rather than via raising an exception. In this case, the NULL op_next of the OP_ENTEREVAL was passed to a new RUNOPS loop, which would normally SEGV (or on debugging builds, warn "NULL OP IN RUN"). (cherry picked from commit 16e43ef)
Module: perl
Description
When I run
"test" =~ m{(?{eval {exists $test[-1]{test}}})}sxx
(fails all the time)Steps to Reproduce
Run.
Expected behavior
Not panic.
Perl configuration
The text was updated successfully, but these errors were encountered: