Server IP : 85.214.239.14 / Your IP : 3.22.242.169 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/3/cwd/proc/3/cwd/usr/share/perl5/B/Hooks/EndOfScope/PP/ |
Upload File : |
# Implementation of a pure-perl on_scope_end for perls < 5.10 # (relies on lack of compile/runtime duality of %^H before 5.10 # which makes guard object operation possible) package # hide from the pauses B::Hooks::EndOfScope::PP::HintHash; use strict; use warnings; our $VERSION = '0.26'; use Scalar::Util (); use constant _NEEDS_MEMORY_CORRUPTION_FIXUP => ( "$]" >= 5.008 and "$]" < 5.008004 ) ? 1 : 0; use constant _PERL_VERSION => "$]"; # This is the original implementation, which sadly is broken # on perl 5.10+ within string evals sub on_scope_end (&) { # the scope-implicit %^H localization is a 5.8+ feature $^H |= 0x020000 if _PERL_VERSION >= 5.008; # the explicit localization of %^H works on anything < 5.10 # but we use it only on 5.6 where fiddling $^H has no effect local %^H = %^H if _PERL_VERSION < 5.008; # Workaround for memory corruption during implicit $^H-induced # localization of %^H on 5.8.0~5.8.3, see extended comment below bless \%^H, 'B::Hooks::EndOfScope::PP::HintHash::__GraveyardTransport' if ( _NEEDS_MEMORY_CORRUPTION_FIXUP and ref \%^H eq 'HASH' # only bless if it is a "pure hash" to start with ); # localised %^H behaves funny on 5.8 - a # 'local %^H;' # is in effect the same as # 'local %^H = %^H;' # therefore make sure we use different keys so that things do not # fire too early due to hashkey overwrite push @{ $^H{sprintf '__B_H_EOS__guardstack_0X%x', Scalar::Util::refaddr(\%^H) } ||= bless ([], 'B::Hooks::EndOfScope::PP::_SG_STACK') }, $_[0]; } sub B::Hooks::EndOfScope::PP::_SG_STACK::DESTROY { B::Hooks::EndOfScope::PP::__invoke_callback($_) for @{$_[0]}; } # This scope implements a clunky yet effective workaround for a core perl bug # https://rt.perl.org/Public/Bug/Display.html?id=27040#txn-82797 # # While we can not prevent the hinthash being marked for destruction twice, # we *can* intercept the first DESTROY pass, and squirrel away the entire # structure, until a time it can (hopefully) no longer do any visible harm # # There still *will* be corruption by the time we get to free it for real, # since we can not prevent Perl's erroneous SAVEFREESV mark. What we hope is # that by then the corruption will no longer matter # # Yes, this code does leak by design. Yes it is better than the alternative. { my @Hint_Hash_Graveyard; # "Leak" this entire structure: ensures it and its contents will not be # garbage collected until the very very very end push @Hint_Hash_Graveyard, \@Hint_Hash_Graveyard if _NEEDS_MEMORY_CORRUPTION_FIXUP; sub B::Hooks::EndOfScope::PP::HintHash::__GraveyardTransport::DESTROY { # Resurrect the hinthash being destroyed, persist it into the graveyard push @Hint_Hash_Graveyard, $_[0]; # ensure we won't try to re-resurrect during GlobalDestroy bless $_[0], 'B::Hooks::EndOfScope::PP::HintHash::__DeactivateGraveyardTransport'; # Perform explicit free of elements (if any) triggering all callbacks # This is what would have happened without this code being active %{$_[0]} = (); } } 1;