# New Ticket Created by Jeff Horwitz # Please include the string: [perl #60030] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=60030 >
a while back in #parrot, i reported a rakudo segfault when calling "use" with a multilevel namespace: ./parrot --gc-debug languages/perl6/perl6.pbc -e 'use Foo::Bar' chromatic was able to reproduce, but debugging proved to be difficult. however, i've since been able to narrow it down to a simple pure-PIR test case: === .sub doit .param string s $I0 = index s, '::' say s substr s, $I0, 2, "/" say s collect say s .end .sub main :main doit('Foo::Bar') .end [EMAIL PROTECTED] parrot]$ ./parrot foo.pir Foo::Bar Foo/Bar Segmentation fault === i used the "collect" opcode instead of --gc-debug as it helped with debugging. in any case, the backtrace shows that the string buffer for s is no longer valid after collect: (gdb) p *s $1 = {cache = {_b = {_bufstart = 0x2b648e5d5ad8, _buflen = 8}, _ptrs = { _struct_val = 0x2b648e5d5ad8, _pmc_val = 0x8}, _i = { _int_val = 47710885206744, _int_val2 = 8}, _num_val = 2.357230931332755e-310, _string_val = 0x2b648e5d5ad8}, flags = 131328, strstart = 0x2b648e5d5ad8 <Address 0x2b648e5d5ad8 out of bounds>, bufused = 7, strlen = 7, hashval = 0, encoding = 0x60ab10, charset = 0x60c250} after seeing that, i ran it again, setting a watchpoint on s->strstart so i could see exactly when it was freed. the culprit is compact_pool, and i was able to get the backtrace from the corresponding free(): Breakpoint 4, 0x00002b87ad29fa90 in free () from /lib64/libc.so.6 (gdb) bt #0 0x00002b87ad29fa90 in free () from /lib64/libc.so.6 #1 0x00002b87ab8a09bc in mem__internal_free (from=0x2b87ad794010, file=0x2b87abaa2dc8 "src/gc/resources.c", line=531) at src/gc/memory.c:328 #2 0x00002b87ab9692d5 in compact_pool (interp=0x609080, pool=0x60a4e0) at src/gc/resources.c:531 #3 0x00002b87ab969390 in Parrot_go_collect (interp=0x609080) at src/gc/resources.c:564 #4 0x00002b87ab8275d9 in Parrot_collect (cur_opcode=0x983700, interp=0x609080) at src/ops/core.ops:1187 #5 0x00002b87ab8dc65f in runops_slow_core (interp=0x609080, pc=0x983700) at src/runops_cores.c:222 #6 0x00002b87ab8adbd4 in runops_int (interp=0x609080, offset=22) at src/interpreter.c:937 #7 0x00002b87ab8ae5c3 in runops (interp=0x609080, offs=22) at src/inter_run.c:101 #8 0x00002b87ab8ae899 in runops_args (interp=0x609080, sub=0x960f18, obj=0x663350, meth_unused=0x0, sig=0x2b87aba9bf03 "vP", ap=0x7fffff60ad50) at src/inter_run.c:236 #9 0x00002b87ab8aea8b in Parrot_runops_fromc_args (interp=0x609080, sub=0x960f18, sig=0x2b87aba9bf03 "vP") at src/inter_run.c:300 #10 0x00002b87ab8943fe in Parrot_runcode (interp=0x609080, argc=1, argv=0x7fffff60b048) at src/embed.c:951 #11 0x00002b87aba75568 in imcc_run_pbc (interp=0x609080, obj_file=0, output_file=0x0, argc=1, argv=0x7fffff60b048) at compilers/imcc/main.c:791 #12 0x00002b87aba75f77 in imcc_run (interp=0x609080, sourcefile=0x7fffff60bc42 "foo.pir", argc=1, argv=0x7fffff60b048) at compilers/imcc/main.c:1079 #13 0x0000000000400b14 in main (argc=1, argv=0x7fffff60b048) at src/main.c:61 i'm not sure if this is compact_pool's fault or if it's just the messenger, but obviously the string is still in use and shouldn't be freed. 2 other things i noted: 1) this only segfaults if the original string is passed as an argument to a subroutine. for example, this works just fine: .sub main :main $S0 = 'Foo::Bar' $I0 = index $S0, '::' say $S0 substr $S0, $I0, 2, "/" say $S0 collect say $S0 .end 2) substr has some COW semantics, which may be relevant, but i'm not sure. -jeff