Discussion:
Variable suicide
(too old to reply)
Tassilo von Parseval
2005-12-10 09:24:43 UTC
Permalink
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);
Steven N. Hirsch
2005-12-10 14:32:29 UTC
Permalink
Post by Tassilo von Parseval
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
(gdb) break Lib.xs:380
No symbol table is loaded. Use the "file" command.
Newer gdb versions handle deferred breakpoints, but in the past I've
created a "do nothing" xs routine which sends itself a SIGUSR2 and called
that from a Perl before doing anything meaningful with the extension.
When it breaks into the debugger, everything is loaded and you can set the
"real" breakpoint and continue.

Steve

Loading...