Update: The long and short of it is that I was doing it myself. When the thread ends, my DESTROY() function is called; which was freeing up the memory. The corruption was the free memory tags used by the allocator!

The fact that the object still "worked" after it memory was all freed is just luck.


I have an XS module that presents as class; by returning a pointer to the internal C struct wrapped up in a blessed RV->IV using sv_setref_pv().

In single threaded code this works perfectly.

And if I return the object reference from a thread, once I get it back in the main thread, it still "works". That is, invoking methods on the returned (cloned) blessed reference invokes the appropriate code, and the wrapped over C pointer still points to the appropriate data.

However, some corruption has crept in to the referenced structure. Or rather, another structure (a C array of structs) referenced from within the referenced struct. (I know; as clear as mud; but please bear with me if you are likely to be able to help.)

The code at the bottom of the post produces this output, though I reformatted it here for discussion purposes.

The left-hand side is produced (Devel::Peek::Dump) from within the thread once the object has been populated. The right-hand side is produced back in the main thread once the bless ref has been passed back via join:

SV = RV(0x4b1e750) at 0x4b1e740 + SV = RV(0x4386f70) at 0x4386f60 REFCNT = 1 + REFCNT = 1 FLAGS = (PADMY,ROK) + FLAGS = (PADMY,ROK) RV = 0x4b229c0 + RV = 0x2977b0 SV = PVMG(0x4b032d8) at 0x4b229c0 + SV = PVMG(0x424f3b8) at 0x2977b0 REFCNT = 1 + REFCNT = 1 FLAGS = (OBJECT,IOK,POK,pIOK,pPOK) + FLAGS = (OBJECT,IOK,POK,pIOK,pPOK) IV = 49572896 + IV = 49572896 NV = 0 + NV = 0 PV = 0x4b5eb38 "49572896"\0 + PV = 0x4b5ead8 "49572896"\0 CUR = 8 + CUR = 8 LEN = 16 + LEN = 16 STASH = 0x442c448 "BiMap" + STASH = 0x297870 "BiMap"

Whilst most of the values have changed due to the cloning; the two salient parts: 1) the C pointer held in the IV field; 2) the package/class associated with the stash; have survived the cloning intact. And indeed, the cloned blessed ref still works as an object.

However, when I dump the contents of the object pre & post cloning; the content of the C data has been subtly corrupted; and in a way that utterly baffles me.

For reference, here are the two struct definitions involved:

typedef struct { U64 addr; char *name; } PAIR; typedef struct { PAIR **byInt; U32 *byStr; U32 size; U32 used; double factor; } BIMAP;

The blessed reference contains a pointer to a BIMAP struct; which in turn contains two pointer to arrays; one of PAIR structs; the other of U32s.

And the dumps: again, the left-hand side comes from within the thread; the right-hand side back in the main thread:

Object:0000000002F46C20 byInt:0000000002F46C50 byStr:0000000002F46E60 +size:32 used:26 Object:0000000002F46C20 byInt:0000000002F46C50 byStr: +0000000002F46E60 size:32 used:26 0: pair:[00000000000E6220] 0000000013 m [ byStr: 29 ] + 0: pair:[00000000000E89A0] 0049572176 αλ? [ + byStr: 29 ] 1:[EMPTY SLOT] [ byStr: 0 ] + 1: pair:[00000000000E0158] 0000952736 X?? [ + byStr: 0 ] 2: pair:[00000000000E6280] 0000000016 p [ byStr: 7 ] + 2: pair:[00000000000E6280] 0000000036 p [ + byStr: 7 ] 3:[EMPTY SLOT] [ byStr: 0 ] + 3:[EMPTY SLOT] [ + byStr: 0 ] 4:[EMPTY SLOT] [ byStr: 0 ] + 4:[EMPTY SLOT] [ + byStr: 0 ] 5: pair:[00000000000E60C0] 0000000002 b [ byStr: 0 ] + 5: pair:[00000000000E60C0] 0000000042 b [ + byStr: 0 ] 6: pair:[00000000000E6200] 0000000012 l [ byStr: 12 ] + 6: pair:[00000000000E6200] 0000000014 l [ + byStr: 12 ] 7: pair:[00000000000E6360] 0000000023 w [ byStr: 20 ] + 7: pair:[00000000000E6360] 0000000034 w [ + byStr: 20 ] 8: pair:[00000000000E60E0] 0000000003 c [ byStr: 16 ] + 8: pair:[00000000000E60E0] 0000000056 c [ + byStr: 16 ] 9: pair:[00000000000E60A0] 0000000001 a [ byStr: 3 ] + 9: pair:[00000000000E60A0] 0000000016 a [ + byStr: 3 ] 10: pair:[00000000000E6100] 0000000004 d [ byStr: 18 ] + 10: pair:[00000000000E6100] 0000000012 d [ + byStr: 18 ] 11: pair:[00000000000E6140] 0000000006 f [ byStr: 9 ] + 11: pair:[00000000000E6140] 0000000018 f [ + byStr: 9 ] 12: pair:[00000000000E6160] 0000000007 g [ byStr: 23 ] + 12: pair:[00000000000E6160] 0000000022 g [ + byStr: 23 ] 13: pair:[00000000000E61E0] 0000000011 k [ byStr: 6 ] + 13: pair:[00000000000E61E0] 0000000024 k [ + byStr: 6 ] 14: pair:[00000000000E6260] 0000000015 o [ byStr: 11 ] + 14: pair:[00000000000E6260] 0000000032 o [ + byStr: 11 ] 15: pair:[00000000000E6300] 0000000020 t [ byStr: 15 ] + 15: pair:[00000000000E6300] 0000000040 t [ + byStr: 15 ] 16: pair:[00000000000E6340] 0000000022 v [ byStr: 10 ] + 16: pair:[00000000000E6340] 0000000050 v [ + byStr: 10 ] 17: pair:[00000000000E63A0] 0000000025 y [ byStr: 13 ] + 17: pair:[00000000000E63A0] 0000000054 y [ + byStr: 13 ] 18: pair:[00000000000E63C0] 0000000026 z [ byStr: 21 ] + 18: pair:[00000000000E63C0] 0000000060 z [ + byStr: 21 ] 19: pair:[00000000000E62A0] 0000000017 q [ byStr: 25 ] + 19: pair:[00000000000E62A0] 0000000062 q [ + byStr: 25 ] 20: pair:[00000000000E6120] 0000000005 e [ byStr: 26 ] + 20: pair:[00000000000E6120] 0000000044 e [ + byStr: 26 ] 21: pair:[00000000000E61A0] 0000000009 i [ byStr: 1 ] + 21: pair:[00000000000E61A0] 0000000020 i [ + byStr: 1 ] 22: pair:[00000000000E6240] 0000000014 n [ byStr: 19 ] + 22: pair:[00000000000E6240] 0000000028 n [ + byStr: 19 ] 23: pair:[00000000000E61C0] 0000000010 j [ byStr: 0 ] + 23: pair:[00000000000E61C0] 0000000038 j [ + byStr: 0 ] 24: pair:[00000000000E62C0] 0000000018 r [ byStr: 0 ] + 24: pair:[00000000000E62C0] 0000000030 r [ + byStr: 0 ] 25: pair:[00000000000E62E0] 0000000019 s [ byStr: 24 ] + 25: pair:[00000000000E62E0] 0000000046 s [ + byStr: 24 ] 26: pair:[00000000000E6180] 0000000008 h [ byStr: 28 ] + 26: pair:[00000000000E6180] 0000000048 h [ + byStr: 28 ] 27: pair:[00000000000E6320] 0000000021 u [ byStr: 22 ] + 27: pair:[00000000000E6320] 0000000026 u [ + byStr: 22 ] 28: pair:[00000000000E6380] 0000000024 x [ byStr: 27 ] + 28: pair:[00000000000E6380] 0000000052 x [ + byStr: 27 ] 29:[EMPTY SLOT] [ byStr: 17 ] + 29:[EMPTY SLOT] [ + byStr: 17 ] 30:[EMPTY SLOT] [ byStr: 8 ] + 30:[EMPTY SLOT] [ + byStr: 8 ] 31:[EMPTY SLOT] [ byStr: 14 ] + 31:[EMPTY SLOT] [ + byStr: 14 ]

Things to note:

The question is simple: What the ..... HELP!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Probably not helpful, but here's a (hand constructed) memory map of the layout of the data:

The code:


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
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". I'm with torvalds on this
In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

In reply to [XS] Cloning is corrupting my privates. (Solved!) 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.