# New Ticket Created by chromatic
# Please include the string: [perl #46601]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=46601 >
Run t/pmc/io.t with the GC debugging runcore:
$ TEST_PROG_ARGS='--runcore=gcdebug' prove t/pmc/io.t
Test 42 should fail:
src/string.c:472: failed assertion '!PObj_on_free_list_TEST(a)'
Backtrace - Obtained 17 stack frames (max trace depth is 32).
(unknown)
Parrot_confess
string_append
(unknown)
(unknown)
PIO_putps
Parrot_print_sc
(unknown)
(unknown)
(unknown)
(unknown)
Parrot_runops_fromc_args
Parrot_runcode
imcc_run
(unknown)
__libc_start_main
(unknown)
Program received signal SIGABRT, Aborted.
This means that it's trying to use a STRING that's on the free list. Bad
news:
(gdb) up 4
#4 0xb7ce44f8 in string_append (interp=0x804e008, a=0x81cbb1c, b=0x81f3c7c)
at src/string.c:472
472 saneify_string(a);
(gdb) l
467
468 /* Is A real? */
469 if (a == NULL || PObj_bufstart(a) == NULL)
470 return string_copy(interp, b);
471
472 saneify_string(a);
With a little bit of tracing (hint: set a breakpoint on new_string_header()
just before it returns but only if it's returning the pointer involved in
this expression, then find that breakpoint just before the crash; then do a
backtrace and see what's allocating that PObj and figure out why it's not
marking it properly), the culprit is:
PIO_string_write(PARROT_INTERP, NOTNULL(ParrotIOLayer *l), SHIM(ParrotIO *io),
NOTNULL(STRING *s))
{
STRING * const old_string = (STRING *)l->self;
if (!old_string) {
l->self = s;
return s->strlen;
}
*** l->self = string_append(interp, old_string, s); ***
return string_length(interp, (STRING *)l->self);
}
The ParrotIOLayer's void pointer now points to a PObj, but what do you want to
bet that you can't find that that pointer ever gets marked during DOD? (I
couldn't.) We can paper around this bug with:
dod_register_pmc(interp, l->self);
... just after the string_append() line, but that's a good way to leak STRINGs
by permanently pinning them in memory (and it's a misuse of the function, at
least if you go by its name).
However, it does mean that if we keep up this line of thinking, we do need a
way to identify ParrotIOLayers that hold PObj pointers and mark those
pointers during DOD.
-- c