# 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