Branch: refs/heads/yves/fix_20396 Home: https://github.com/Perl/perl5 Commit: 68e6c89b38716e0fcc94ce39afd96885602157a8 https://github.com/Perl/perl5/commit/68e6c89b38716e0fcc94ce39afd96885602157a8 Author: Yves Orton <demer...@gmail.com> Date: 2022-10-18 (Tue, 18 Oct 2022)
Changed paths: M perl.c Log Message: ----------- perl.c - add debug output to show when the run_body() continues after eval fail This can be helpful debugging issues related to phaser blocks and eval. Commit: 390e2466c3923ed21e88b4ea48ddd687234e1067 https://github.com/Perl/perl5/commit/390e2466c3923ed21e88b4ea48ddd687234e1067 Author: Yves Orton <demer...@gmail.com> Date: 2022-10-18 (Tue, 18 Oct 2022) Changed paths: M scope.c Log Message: ----------- scope.c - sanity check a var before we use it Commit: 32d56cd49b5da95468923e3e927b1f7d22a120e2 https://github.com/Perl/perl5/commit/32d56cd49b5da95468923e3e927b1f7d22a120e2 Author: Yves Orton <demer...@gmail.com> Date: 2022-10-18 (Tue, 18 Oct 2022) Changed paths: M dist/Attribute-Handlers/lib/Attribute/Handlers.pm Log Message: ----------- Attribute-Handlers: rework eval code This makes the logic a bit simpler, and makes it easier to debug as well. Reducing the amount of code that needs to be inside the eval makes it easier to debug what is going on, especially from an internals point of view (eg with -Dl enabled). Commit: 75345d97d282e8f6421dac42445812a37daacc32 https://github.com/Perl/perl5/commit/75345d97d282e8f6421dac42445812a37daacc32 Author: Yves Orton <demer...@gmail.com> Date: 2022-10-18 (Tue, 18 Oct 2022) Changed paths: M perl.c M pp_ctl.c M t/op/eval.t Log Message: ----------- pp_ctl.c - make sure we dont leak PL_restartop from failed compile Fix GH Issue #20396, try_yyparse() breaks Attribute::Handlers. Reduced test case is: perl -e'CHECK { eval "]" }' which should not assert or segfault. In c304acb49 we made it so that when doeval_compile() is executed and it calls yyparse() inside of an eval any exceptions that occur during the parse process are trapped by try_yyparse() so that exection would return to doeval_compile(). This was done so that post eval compilation cleanup logic could be handled similarly regardless of whether Perl_croak() was called or not. However the logic to setup PL_restartop was not adjusted accordingly. The opcode that calls doeval_compile() setups an eval context data before it calls doeval_compile(). This data includes the "retop" which is used to return control to after the eval should it die and is set to the be the evaling opcodes op_next. When Perl_die_unwind() is called it sets PL_restartop to be the "retop" of the of the current eval frame, and then does a longjmp, on the assumption it will end up inside of a "run loop enabled jump enviornment", where it restarts the run loop based on the value of PL_restartop, zeroing it aftewards. After c304acb49 however, a die inside of try_yyparse the die_unwind returns control back to the try_yyparse, which ignores PL_restartop, and leaves it set. Code then goes through the "compilation failed" branch and execution returns to PL_restartop /anyway/, as PL_op hasn't changed and pp_entereval returns control to PL_op->op_next, which is what we pushed into the eval context anyway for the PL_restartop. The end result of this however is that PL_restartop remains set when we enter perl_run() for the first time. perl_run() is a "run loop enabled jump enviornment" which uses run_body() to do its business, such that when PL_restartop is NULL it executes the just compiled body of the program, and when PL_restartop is not null it assumes it must be in the eval handler from an eval from the main body and it should recontinue. The leaked PL_restartop is thus executed instead of the main program body and things go horribly wrong. This patch changes it so that when try_yyparse traps an exception we restore PL_restartop back to its old value. Same for its partner PL_restartjmpenv. This is fine as they have been set to the values from the beginning of the eval frame which we are part of, which is now over. Commit: 78bb4e5a6f20e79d47524f6d148a668e0376d24e https://github.com/Perl/perl5/commit/78bb4e5a6f20e79d47524f6d148a668e0376d24e Author: Yves Orton <demer...@gmail.com> Date: 2022-10-18 (Tue, 18 Oct 2022) Changed paths: M pp_ctl.c Log Message: ----------- pp_ctl.c - try_run_unitcheck() guard against leaking PL_restartop If we die while executing a UNITCHECK inside of an eval we shouldn't leave PL_restartop set, as we will execute PL_op->op_next anyway. I couldn't get anything to SEGV with code related to this, but I could get asserts() to trip to show the leaking PL_restartop. This maintains equivalence with try_yyparse() which does need it for sure. Compare: https://github.com/Perl/perl5/compare/32d136b2d97d...78bb4e5a6f20