in reply to Re^17: Perl crash during perl_clone
in thread Perl crash during perl_clone

I had tried, but the SWIG typemaps I have currently did not allow the 'modulename:subname' format to register the callbacks.

I don't understand this. The SWIG stuff wraps the registering of the CCB, not the PCB.

So you "register" the PCB--by storing the SV* you pass into your code. You then call that stored SV* (using call_sv()) when the SWIG stuff calls back you CCB.

I agree that call_sv() should handle coderefs (according to the documentation; I even think I've done it in the past on 5.8x era perls), but every time I've tried it recently, it falls in a heap with coderefs (with or without threads involved), and works as advertised with a function name. So I stick with the latter. It does mean you have to name the callbacks rather than use anonymous subs or blocks, but that is an acceptable limitation (for me).

I having trouble understanding why you cannot do the same?


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.
RIP an inspiration; A true Folk's Guy

Replies are listed 'Best First'.
Re^19: Perl crash during perl_clone
by perlmonk1729 (Acolyte) on Nov 08, 2010 at 18:07 UTC

    I may have made some other mistake when I tried the SWIG wrapper experiment.

    Its quite late in the night here and I hope I'm not celebrating too early: I think I figured out the cause for the seg-faults in the sample code (myModule version) and my real project.

    The problem seems to be that the \&module:sub syntax is somehow a temporary reference and was out of scope by the time my callback was invoked. The reason it worked in one of my callbacks was sheer coincidence: a scalar that was holding a reference to the sub was still in scope when the callback is called.

    In the RegisterCB function, by doing a newSVsv() and then using that new SV as the PCB always seem to keep the reference in scope/valid when the PCB is called. This newSVsv() was in the first version of my code that did the perl_clone, but I had removed it along with a bunch of other code, thinking it was not necessary.

    I'll try to reconfirm tomorrow when I'm more awake :-) Let me know if it works for you and if it makes sense.

      Let me know if it works for you and if it makes sense.

      Sorry, you lost me there ) I can't see where you could put newSVsv() in RegisterCB(); much less need to...

      'fraid you'll have to draw me a picture of that one :)

        I tried to understand the errors ("undefined subroutine, not a CODE ref) and added Perl_sv_dump while the SV is being registered and before call_sv. It confirmed that a code-ref was properly being registered/cached, but by the time it came to calling the PCB, its "contents" had changed (i.e "printf sv" prints same value, but Perl_sv_dump shows changes).

        I'm a novice at the perl-internal reprenstations, but picked up enough bits that led to my theory :-)

        This is a print from my real project, as I was caching/registering a PCB. The "SV = PVCV", the correct "module-name", "subname" and the rest of the details in the sv_dump print suggested the code-ref was correct at registration time.

        SV = RV(0xa519e7c) at 0xa519e70 REFCNT = 1 FLAGS = (PADMY,ROK) RV = 0xa51a290 SV = PVCV(0xa4fd0e8) at 0xa51a290 REFCNT = 2 FLAGS = () COMP_STASH = 0x98a2d30 "module-name" ... caching perl-sub ref 173121136d in 159850504d context

        Here is the output when the PCB gets called (and gives an "not a CODE ref" error).

        context is 159850504d is calling 173121136d SV = RV(0xa519e7c) at 0xa519e70 REFCNT = 1 FLAGS = (PADSTALE,PADMY) ....

        Note the 'context' and 'sv' values printed are as expected. However, the details (e.g "FLAGS" and others not shown) are totally different. In addition, FLAGS says "STALE" (anything stale cannot be good). Also, it wasnt a "PVCV" anymore.

        That got me thinking if somehow it was "going out of scope" (not sure thats the correct term to use)

        So, I added the newSVsv() just before caching the PCB. See the revised snippet from the myModule.xs that I shared earlier.

        RegisterCB2 (SV *SubRef) CODE: cb_ptr2 = newSVsv(SubRef); printf("registered %lud\n", cb_ptr2); Perl_sv_dump(orig_perl, cb_ptr2); RETVAL = 1; OUTPUT: RETVAL

        Note: I'vent dont anything since last night, so I may still revise this based on any test failures. Also, I will experiment with the 'modname:subname' syntax with SWIG. Will update after that.