A plea from Rakudo-land

Vasily Chekalkin bacek at bacek.com
Sat Jul 4 10:57:48 UTC 2009


Patrick R. Michaud wrote:
> Lest we think this is just a 64-bit problem, here's S04-statements/do.t
> 
>                   x86_64    x86
>    make            pass    abort
>    perl6           pass    abort
>    parrot          pass    abort
>    parrot -G       pass    pass
> 
> A bizarre note about S04-statements/do.t -- it's only the fudged version
> (do.rakudo) that aborts.  The unfudged version (do.t) runs to completion 
> on x86 without aborting, albeit with the (expected) 10 test failures.


O HAI. I spent few hours in investigations. Now I almost sure that 
problem is in marking objects on C stack. Unfortunately my GC-fu is low 
and I can't fix it. But fwiw steps to catch error.

1. Apply this patch to parrot:

diff --git a/src/ops/object.ops b/src/ops/object.ops
index 91662cf..87ef846 100644
--- a/src/ops/object.ops
+++ b/src/ops/object.ops
@@ -60,6 +60,8 @@ op callmethodcc(invar PMC, in STR) :object_base :flow {
    opcode_t *dest              = NULL;
    interp->current_args        = current_args;

+  PARROT_ASSERT(PMC_IS_NULL(method_pmc) || 
!PObj_on_free_list_TEST(method_pmc));
+
    if (PMC_IS_NULL(method_pmc)) {
      PMC * const _class = VTABLE_get_class(interp, object);
      if (PMC_IS_NULL(_class)) {


This is ensuring that we have correct PMC to invoke.

2. Run "gdb --args parrot/parrot -R gcdebug --gc-debug ./perl6.pbc 
t/spec/S04-statements/do.rakudo"

I have Rakudo 6a4d66a94, Parrot r39872.

3. Wait till crash. Inspect backtrace.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb6c786c0 (LWP 24866)]
0xb686b881 in do_dispatch (interp=0x941c040, self=0x9548a10, 
candidates=0x9c6d680, proto=0x947ffd0,
     pos_args=0x9d5cf68, named_args=0x9a87f70, many=1, num_candidates=1, 
next=0x0, cache=0x0)
     at ./perl6multisub.pmc:541
541	    const INTVAL     num_args         = VTABLE_elements(interp, 
pos_args);

(gdb) up 5
#5  0xb7c5a88f in Parrot_callmethodcc_p_sc (cur_opcode=0xb693fb1c, 
interp=0x941c040)
     at src/ops/object.ops:82
82	    dest                   = VTABLE_invoke(interp, method_pmc, next);
(gdb) p *method_pmc
$25 = {cache = {_b = {_bufstart = 0x9d5cfc8, _buflen = 0}, _ptrs = 
{_struct_val = 0x9d5cfc8,
       _pmc_val = 0x0}, _i = {_int_val = 165007304, _int_val2 = 0}, 
_num_val = 8.1524440219282904e-316,
     _string_val = 0x9d5cfc8}, flags = 524288, vtable = 0xdeadbeef, data 
= 0x0, pmc_ext = 0xdeadbeef}


As we can see C<method_pmc> was collected prematurely. Patch from step 1 
asserts that C<method_pmc> was correct _before_ calling VTABLE_invoke.

Hope this will help Whiteknight/chromatic/anyone else. I almost failed 
in Sanity save roll even with chromatic's assist :)

-- 
Bacek


More information about the parrot-dev mailing list