in reply to [XS] Callbacks to perl

I think you leaked ST(0). It comes from Adder already mortaled. You increased the refcount, but didn't remortal it (unless the mortal is in the C version after XSPP does its job). As I understand each sv_2mortal will put the SV once on mortal stack. Each mortal must own one notch on the refcount and it all is supposed to balance out in the end. Perl interp fatally errors if it double frees a SV. I often omit SAVE/FREETMPS, I dont omit the ENTER/LEAVE since I don't have a good understanding when its safe to omit ENTER/LEAVE. I would use a POPs rather than fix up ax and get ST() working again, smaller machine code then. I'm not sure if the count check makes sense, I think G_SCALAR will FORCE the count to be 1 or 0 (or is that 1, a immortal undef is always placed if the callee return a 0 length list?), and it will mortal and delete the excess SVs off the perl stack before giving it to you.

Replies are listed 'Best First'.
Re^2: [XS] Callbacks to perl
by syphilis (Archbishop) on Jun 18, 2012 at 01:07 UTC
    I think you leaked ST(0)

    I added a wrapping of PL_sv_count to the Inline::C script:
    void wrap_count() { printf("wrap_count: %d\n", PL_sv_count); }
    If I call wrap_count() after each call to call_Adder() I find that the count has remained the same. I *think* that means that no leaking has occurred.
    Also, if I sv_2mortal(ST(0)); before returning ST(0) I get the "Attempt to free unreferenced scalar" warning again.

    I dont omit the ENTER/LEAVE since I don't have a good understanding when its safe to omit ENTER/LEAVE

    Turns out I can put them in without the script suffering any adverse effect, so I think I might do that. I could also re-instate SAVETMPS/FREETMPS if necessary, but I'll leave them out for now. (All 4 caused me some grief in my earlier attempts to get this script working, so I removed them and didn't get around to checking whether they did, in fact, really *need* to be removed.)

    I'm not sure if the count check makes sense

    Yes, it's something I've just copied verbatim from the perlcall examples, without any appreciation of it's siginificance. The error message is "Big trouble", which would be a very appropriate message if G_SCALAR is supposed to force the count as you say ;-)

    Thanks for the feedback.
    Please let me know if I'm still missing something.

    Cheers,
    Rob
      Also, if I sv_2mortal(ST(0)); before returning ST(0) I get the "Attempt to free unreferenced scalar" warning again.

      XSPP (I know your using something different), if you make a XS func with SV * as the return type, rather than void and PPCODE:, XSPP will throw in a sv_2mortal secretly on the "return" SV *. I always put " XSOPT => ' -nolinenumbers '," in my makefile.pl since the #line preprocessor that XSPP puts in drive my C debugger mad.

      I'm not sure if the count check makes sense

      Yes, it's something I've just copied verbatim from the perlcall examples, without any appreciation of it's siginificance. The error message is "Big trouble", which would be a very appropriate message if G_SCALAR is supposed to force the count as you say ;-)


      I reread the perl source code, egh, the count check makes sense, see perl.c#l2736 in perl.git and pp_hot.c#l2776 in perl.git, sometimes perl fixes up the stack, often it doesn't, I guess from reading the code. If adder() is something you wrote and control, put the count check in a assert, the runtime overhead isn't worth it. PL_sv_count tip is great. I never knew that before. I also think (its been a while since the first and last time I did it), if you leave out the PUSHMARK, the callee will inherit your XSUB's stack/@_, sometimes its what you want. I generally keep the SAVE/FREETMPS out, I know the caller/entersub will clean up the mortals for me normally. By batching more mortals together for freeing, I will presume its faster than 2 separate SV freeing sessions because of CPU caching. Of course follow the event loop warning in perlcall. The ax fixup I can't comment on.
        PL_sv_count tip is great. I never knew that before

        I didn't know about it either, until someone here at perlmonks came up with the idea a few months back. I forget who it was (... with apologies to the OP).

        The ax fixup I can't comment on

        I've switched to returning a POPs instead, as you suggested. Looks better.

        Thanks again, for *all* that you posted.

        Cheers,
        Rob