[perl #98092] Fix unreferenced scalar warnings in clone.t
Commit
da6b625f78 triggered an unrelated bug, by rearranging things in
memory so that the conditions were right:
If @DB::args has been populated, and then the items in it have been
freed, they can end up being reused for any SV-ish things allocated
thereafter, even lexical pads.
Each CV (subroutine) has a list of pads, called the padlist, which is
the same structure as a Perl array (an AV) underneath. The padlist’s
memory management is done in pad.c, as there are other things that
have to be done when its elements (the pads themselves) are freed.
So, to prevent av.c from trying to free those elements, the padlist is
not marked REAL; i.e., it’s marked as not having its elements refer-
ence-counted, even though they are: it’s just not handled in av.c
The ‘Attempt to free unreferenced scalar’ warnings emitted by
threads::shared’s clone.t occurred when padlists and pads ended up
using freed SVs that were still in @DB::args. When a new thread was
created, the pads in @DB::args ended up getting cloned when @DB::args
was cloned; hence they were treated as non-reference-counting arrays,
and the pads inside them were cloned with a lower reference count than
they ought to have had (sv_dup was called, instead of sv_dup_inc).
The pad-duplication code (pad_dup), like the regular SV-duplication
code, checks first to see if a padlist has been cloned already, before
actually doing it. There was also a problem with pad_dup not incre-
menting the reference count of an already-cloned padlist.
So this commit fixes the pad_dup reference-counting bug and also
leaves AvREAL on for padlists, until the very last moment when they
are freed (in pad_free) with SvREFCNT_dec.