Hi there,

currently something entirely puzzling keeps me busy. I have a sort of
constructor that returns a blessed reference to a C structure using the
traditional 'sv_setref_pv(..., ..., (void*)cstruct)'-thingy. Like so:

    struct event_args *
    timer_new (func, ...)
        SV *func;
    PREINIT:
        static char *CLASS = "Event::Lib::timer";
        struct event_args *args;
    CODE:
    {
        register int i;

        if (GIMME_V == G_VOID)
            XSRETURN_UNDEF;
        
        if (!SvROK(func) && (SvTYPE(SvRV(func)) != SVt_PVCV))
            croak("First argument to timer_new must be code-reference");
        
        New(0, args, 1, struct event_args);
        New(0, args->ev, 1, struct event);
        
        /* populate event_args */
        
        RETVAL = args;
    }
    OUTPUT:
        RETVAL
    CLEANUP:
    {
        evtimer_set(args->ev, CALLBACK_CAST do_callback, (void*)ST(0));
    }

The CLEANUP-thing is necessary because the object to be returned is also
used as an argument to this 'evtimer_set' function (ST(0)) that will at
some later point call the C-function do_callack with this very object.

Depending on how I adjust the ref-count of this object, do_callback
later gets called with an already freed object. The confusing thing
about it is that the DESTROY-method for that blessed reference is never
called. So my question: How and under what circumstances can a proper
Perl object be freed but without ever triggering its DESTROY method?

This is what gdb has to say about it:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 16384 (LWP 10201)]
0x4028b5ed in do_callback (fd=-1, event=1, ev=0x814cd08) at Lib.xs:147
147         struct event_args *args = (struct event_args*)SvIV(SvRV(ev));
(gdb) bt
#0  0x4028b5ed in do_callback (fd=-1, event=1, ev=0x814cd08) at Lib.xs:147
#1  0x40298c99 in event_process_active (base=0x81de470) at event.c:256
#2  0x40298fb4 in event_base_loop (base=0x81de470, flags=0) at event.c:370
#3  0x40298deb in event_loop (flags=0) at event.c:305
#4  0x40298cd0 in event_dispatch () at event.c:268
#5  0x4028f202 in XS_Event__Lib_event_mainloop (my_perl=0x814bf18, 
cv=0x81e53e0) at Lib.xs:481
#6  0x080c32d6 in Perl_pp_entersub ()
#7  0x080bbdc9 in Perl_runops_standard ()
#8  0x080635e8 in perl_run ()
#9  0x080633f5 in perl_run ()
#10 0x0805fb9f in main ()
(gdb) p *ev
$1 = {sv_any = 0x0, sv_refcnt = 1, sv_flags = 0}

One other small thing: I remember I once managed to properly debug XS
modules under gdb but somehow I seem to have lost this ability. Whenever
I try to set a breakpoint, I get:

    (gdb) break Lib.xs:380
    No symbol table is loaded.  Use the "file" command.

And even:

    (gdb) symbol-file blib/arch/auto/Event/Lib/Lib.so
    Reading symbols from
    
/home/ethan/Projects/dists/event-lib/Event-Lib-0.99_9/blib/arch/auto/Event/Lib/Lib.so...done.
    (gdb) break Lib.xs:380
    Breakpoint 1 at 0x5cf1: file Lib.xs, line 380.
    (gdb) run
    Starting program: /usr/bin/perl
    Warning:
    Cannot insert breakpoint 1.
    Error accessing memory address 0x5cf1: Input/output error.

I get the same when I try to set breakpoints on the .c file generated by
xsubpp. How do you folks do that?

Cheers,
Tassilo
-- 
use bigint;
$n=71423350343770280161397026330337371139054411854220053437565440;
$m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);

Reply via email to