If I build parrot with --gc=libc on OS X I see some warnings about bad pointers being passed to free(). It's happening in a call from dod.c:
#ifdef GC_IS_MALLOC /* free allocated space at (int*)bufstart - 1, * but not if it is used COW or external */ if (PObj_bufstart(b) && !PObj_is_external_or_free_TESTALL(b)) { if (PObj_COW_TEST(b)) { INTVAL *refcount = ((INTVAL *)PObj_bufstart(b) - 1); if (!--(*refcount)) free(refcount); /* the actual bufstart */ } else free((INTVAL*)PObj_bufstart(b) - 1); } #else and the PMC in question appears to be the PMC morphed from Undef to String by the concat in this pasm: new P0, .String new P1, .Undef set P0, "foo" concat P1, P0, P0 end As far as I can tell the only difference between a PMC that started as String, and one that started as Undef is that for the String PMC the PMC flags are 512 on entry to the String PMC's init /* PObj is a string */ PObj_is_string_FLAG = 1 << 8, whereas the flags are set to 0 in pmc_reuse and so are 0 on its call to the String PMC's init the PMC flags are zero. What sets the flags to 512 on creation of the String PMC? This functionality seems to be missing from the morph code. Nicholas Clark