develooper Front page | perl.perl5.porters | Postings from March 2017

Re: [perl #32714] Objects destroyed in the wrong order during globaldestruction

Thread Previous | Thread Next
March 14, 2017 12:22
Re: [perl #32714] Objects destroyed in the wrong order during globaldestruction
Message ID:
On 11 March 2017 at 22:16, Leon Timmermans <> wrote:
> On Sat, Mar 11, 2017 at 1:32 PM, Ævar Arnfjörð Bjarmason
> <> wrote:
>> On a related note. At in our web applications we don't run
>> destruction beyond just destroying the Plack $env, then we
>> POSIX::_exit(). See &
>> for why, but tl;dr: With
>> forked processes it creates a CPU/Memory DoS attack on the kernel as
>> it frantically tries to unshare all the pages whose refcounts change.
>> So uWSGI has an option now to simply skip the perl_destruct() &
>> perl_free() phases, which from my looking at the source & testing it
>> seemed like the sane solution:
>> I can't think of a use-case for this, but is it a good idea to provide
>> some alternative to POSIX::_exit() in this case, i.e. is there some
>> subset of perl_{destruct,free}() that we could run that wouldn't free
>> everything, but e.g. just enough to run any DESTROY handlers?
>> Currently if we have some DESTROY handler hanging off anything but
>> $env it simply won't execute when we teardown the process.
>> I don't know if that's possible or even a mad idea, but since you're
>> poking this code I thought I'd bring this use-case to your attention.
> Perl already has a concept of destruct level, current valid values are
> 0, 1, and 2.
> 0 destructs much of the interpreter and all objects, this is the
> default on unthreaded perls.
> 1 destructs a bit more of the interpreter, in particular the stashes.
> This is the default in an embeded perl with multiplicity enabled.
> 2 destructs absolutely everything, including non-object cycles and the
> global string table. sets it to this value.
> I'm not sure what the value for PL_perl_destruct_level is in your
> particular case, lowering it may help. I can imagine introducing a -1
> level that does little more than run END blocks and flush IO buffers.

Those models dont match the problem Booking is solving. They may match
a different problem but that is a different question.

The issue here is that in a multi-forked process model you want to add
an extra concept: that is which process "owns" the data, and thus is
responsible for the cleanup of the objects involved.

So consider a scenario where we have a mother process which owns an
object, lets say a string. Now we fork, and have the child process do
something, say write some summaries to disk. When that child process
terminates we don't want to it to try to free or destruct any
variables owned by the parent process that the child process hasn't
touched, in this case the string structure owned by the parent.

What happens in a normal scenario is that the refcount page holding
that string is decremented during cleanup by the child, which un-COWs
the page.

If you are using a fork/exec model, the costs of tearing down all the
structures which are effectively RO to the child process can be very
significant, to the point of being a "forkbomb" in disguise.

So we don't tear down, we just kill everything. Avar would like a more
graceful solution that knows that there are some things that the child
should tear down, and that the rest should not be.

Examples of this abound btw, for instance consider PL_strtab. Every
time a child process exits we free up all those keys....

perl -Mre=debug -e "/just|another|perl|hacker/"

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About