If Perl assume all UVs were really pointers to SVs, it would crash left and right.

Remember, I'm only suggesting this can happen during cloning, not normal operations. Remember that SvRVs & SvIVs used to be different types. Maybe the cloning code, written before this amalgamation, only checked for SvTYPE and has never been updated to further distinguish RVs from IV/UVs?

Maybe you have a better explanation for this observed behaviour:

... package main; use threads; use Devel::Peek; my $o = O->new(); print $o; $o->set( "abcde" ); print $o->get(); print "\nthreaded\n"; async { print $o->get( ); $o->set( 12345 ); print $o->get( ); }->join; print $o->get(); __END__ C:\test>xso N:rv:000000000035E128 o:0000000003FFA818 O=SCALAR(0x3ffa818) S:rv;000000000035E248 o:0000000003C318F0 G:rv;000000000035E248 o:0000000003C318F0 old:000000000035E128 abcde threaded G:rv;0000000004258CA8 o:0000000004229090 old:0000000000000000 S:rv;0000000004258CA8 o:0000000004229090 G:rv;0000000004258CA8 o:0000000004229090 old:0000000004259920 12345 G:rv;000000000035E248 o:0000000003C318F0 old:000000000035E128 abcde

Before the thread, I set a value into the struct, and get it back.

Then I move into the thread, the RV gets cloned, the SvUV it points to gets cloned; but the value within the SvUV (labelled 'o:' in the printfs), also changes. And as the numeric value inside the UV (which we know is a pointer but Perl shouldn't), has also changed. It no longer points to the original struct. Hence, 'old:' no longer has a value.

I then insert a different value into the struct, and successfully retrieve that value. I then exit the thread and, and get the value again, and lo, I get the original value set, not the one I modified inside the thread.

No, the *only* explanation that I can come up with for that behaviour is that when the RV and UV get cloned, it also clones the thing that the UV points to; even though it shouldn't know that the numberic value in the UV is a pointer. Do you have a better explanation?

The full code:

#! perl -slw use strict; package O; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'END_C', NAME => 'xso', CLEAN_AFTER_BUILD => 0; typedef struct { SV**sv; } O; void *mem( size_t size ) { void *p; Newx( p, size, char ); return p; } SV *new( char *package ) { O *o = (O*)mem( sizeof( O ) ); SV *rv = newRV( (SV*)o ); o->sv = mem( sizeof( SV* ) ); sv_bless( rv, gv_stashpv( package, 0 ) ); SvREADONLY_on( rv ); printf( "N:rv:%p o:%p\n", rv, o ); return rv; } int set( SV *rv, SV *in ) { O *o = ( *(O**)SvUV( rv ) ) - 1; printf( "S:rv;%p o:%p\n", rv, o ); o->sv = newSVsv( in ); return 1; } SV *get( SV *rv ) { O *o = ( *(O**)SvUV( rv ) ) - 1; SV *old = newSVsv( o->sv ); SvREFCNT_inc( old ); printf( "G:rv;%p o:%p old:%p\n", rv, o, o->sv ); return old; } END_C package main; use threads; use Devel::Peek; my $o = O->new(); print $o; $o->set( "abcde" ); print $o->get(); print "\nthreaded\n"; async { print $o->get( ); $o->set( 12345 ); print $o->get( ); }->join; print $o->get();

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

In reply to Re^6: semi-panic: attempt to dup freed string? by BrowserUk
in thread semi-panic: attempt to dup freed string? by BrowserUk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.