Skip Menu |

This queue is for tickets about the Test-Weaken CPAN distribution.

Report information
The Basics
Id: 67778
Status: resolved
Priority: 0/
Queue: Test-Weaken

People
Owner: jkegl [...] cpan.org
Requestors: user42 [...] zip.com.au
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: docs on xsub mortalizing
Date: Wed, 27 Apr 2011 07:27:32 +1000
To: bug-Test-Weaken [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
This is a suggestion for the Test::Weaken docs, at the end of the "ADVANCED TECHNIQUES" section, to give some tips on checking scalars returned by xsubs. The subtle bit is knowning to write $ref = \(myxsub()) or @refs = map {\($_)} myxsub(); and not copy to a local variable as would normally be done.
=head2 XSUB Mortalizing When an XSUB returns a newly created scalar it should "mortalize" so that scalar is freed once the caller has finished with it (see L<perlguts/Reference Counts and Mortality>). Failing to do so leaks memory. SV *ret = newSViv(123); sv_2mortal (ret); /* must mortalize */ XPUSHs (ret); C<Test::Weaken> can check this by taking a reference to the returned scalar, my $leaks = leaks (sub { return \( myxsub() ); }); if ($leaks) ... Don't copy to another local scalar and then return that. Doing so will only check the local C<$copy>, not the scalar returned by C<myxsub()>. If you want the value for extra calculations then take a reference for the return and look through that for the value. leaks (sub { my $ref = \( myxsub() ); my $value = $$ref; # ... do something with $value return $ref; }); If an XSUB returns a list of values then take a reference to each as follows. This works because C<map> and C<for> make the loop variable (C<$_> or named) an alias to each value successively. leaks (sub { return [ map {\$_} myxsub() ]; }); # or with a for loop leaks (sub { my @refs; foreach my $value (myxsub()) { push @refs, \$value; } return \@refs; }); Don't simply store a returned list to an array (either named or anonymous). This copies into new scalars in that array and the returned ones from C<myxsub()> then aren't checked. If you want values from a list for extra calculations then take the references first and look at them for the values like the single case above. For example, leaks (sub { my @refs = map {\$_} myxsub(); my $first_ref = $refs[0] my $value = $$first_ref; # ... do something with $value return \@refs; }); An XSUB could deliberately return the same scalar each time, perhaps a pre-calculated constant or a global variable it maintains. In that case the scalar intentionally won't weaken away and C<leaks()> checking is not applicable. The scalar every time occurs in pure Perl too from an anonymous constant subr, of the kind created by the C<constant> module (see L<constant>). This is unlikely to arise directly, but could be encountered through a scalar ref within an object etc. *FOO = sub () { 123 }; # FOO() returns same scalar every time # likewise from the constant module use constant FOO => 123; There's no way to tell the intended lifespan of an XSUB return, but generally if the code has any sort of C<sv_newmortal> or C<newSV> etc for a new scalar every time then it ought to weaken away. Details of an XSUB return are often hidden in a C<typemap> for brevity and consistency (see L<perlxs/The Typemap>). The supplied types (F<Extutils/typemap>) are hard to get wrong, but code with explicit C<PUSHs()> etc is worth checking. Too much mortalizing generally causes negative refcounts and probable segfaults, not enough mortalizing leaks memory.
I owe more than the usual apology on this one. The delay here amounts to real neglect on my part, and I'm sorry. The nearest thing I have to an excuse was my focus on Marpa. In any case, at long last I have taken action. There is a new Test::Weaken::XSUB document. I added the usual Test::Weaken legal aftermatter, and prefixed a explanation of the new document's authorship. It's Test-Weaken-3.007_000.
The fix is in 3.007_001. I'll wait a few days for cpantesters and other feedback before marking this ticket resolved. On Sun Jan 01 20:45:38 2012, JKEGL wrote: Show quoted text
> I owe more than the usual apology on this one. The delay here amounts > to real neglect on my part, and I'm sorry. The nearest thing I have to > an excuse was my focus on Marpa. > > In any case, at long last I have taken action. There is a new > Test::Weaken::XSUB document. I added the usual Test::Weaken legal > aftermatter, and prefixed a explanation of the new document's > authorship. It's Test-Weaken-3.007_000.
Applied.