Branch: refs/heads/smoke-me/davem/rc_stack2 Home: https://github.com/Perl/perl5 Commit: 3fe82d61f99cef69b642733c096dc3b2b98946f8 https://github.com/Perl/perl5/commit/3fe82d61f99cef69b642733c096dc3b2b98946f8 Author: David Mitchell <da...@iabyn.com> Date: 2023-03-15 (Wed, 15 Mar 2023)
Changed paths: M pp_ctl.c Log Message: ----------- pp_caller(): set @DB::args earlier Copy @_ SV pointers to @DB::args earlier, before pp_caller() has the chance to create any new SVs (e.g. for the package name). This will give the next commit a chance to discover and skip any freed elements in @_. This commit makes no changes to the block of code that is moved; that's saved for the next commit. Commit: f67f2243f29cee7407a9ca0e2c1b2ec22ed0ea73 https://github.com/Perl/perl5/commit/f67f2243f29cee7407a9ca0e2c1b2ec22ed0ea73 Author: David Mitchell <da...@iabyn.com> Date: 2023-03-15 (Wed, 15 Mar 2023) Changed paths: M pp_ctl.c M t/op/caller.t Log Message: ----------- caller(): don't copy freed SV pointer to @DB::args When pp_caller() aliases the elements of @_ to @DB::args, it may include pointers to array elements which have been shifted away. So for example in sub f { my $self = shift; ....; croak() } it populates $DB::args[0] with the SV pointer one position below the AvARRAY() of @_. This means that the argument lists in the stack backtrace provided by croak() will include the original first arg, which is nice, but is very fragile. There is no guarantee that that SV hasn't been freed or reallocated in the meantime. This commit adds a check for each SV pointer being copied to @DB::args, which NULLs it if the SV has a refcount of 0. This means that in something like: package DB: () = caller($i); my @args = @DB::args; perl will no longer panic about copying a freed SV. Note that this commit does not address the issue of the SV having already been reallocated. In the example above, some elements of @args may contain a copy of some other random variable. However, the previous commit moved to earlier in the function, the block of code in pp_caller() which populates @DB::args, to before pp_caller() allocates new SVs for things like the package name. Which means the RC==0 test added by this commit has a better chance of spotting SVs which have been freed but not yet reallocated. In summary, @DB::args is still a horrible, fragile hack, but these two commits make it slightly less fragile in some circumstances. Compare: https://github.com/Perl/perl5/compare/dec99a6d0e02...f67f2243f29c