There is a repeatable segfault when GC is triggered during argument
passing after a tailcall.  The immediate symptom is that clone_key_arg
blows cookies because the current arg is a 0xdeadbeef PMC.  Apparently,
the sweep doesn't see pointers in the old context.  The attached patch
(break-arg-passing.patch) forces a GC during parrot_pass_args, which
causes the attached test case (tailcall-new-pmcs.pir) to segfault as
described.  (I found this bug without break-arg-passing.patch where the
allocation of a :slurpy array (I think) was what triggered the sweep,
but that was in a much larger test case.)

   So I am hoping there is an obvious fix that is better than disabling
GC around parrot_pass_args in the C<get_params> op.  That also does the
job for this case, but clearly wouldn't work if (say) GC was triggered
by C<push_eh> before receiving arguments.

   TIA,

                                        -- Bob Rogers
                                           http://rgrjr.dyndns.org/

Diffs between last version checked in and current workfile(s):

Index: src/inter_call.c
===================================================================
--- src/inter_call.c    (revision 16239)
+++ src/inter_call.c    (working copy)
@@ -1151,6 +1151,7 @@
 
     st.dest.n = 0;      /* XXX */
 
+    Parrot_do_dod_run(interp, 0);
     if (what == PARROT_OP_get_params_pc) {
         dst_pc = interp->current_params;
         src_pc = interp->current_args;

End of diffs.
### test_tail passes new PMCs in a tailcall to list.
.sub list
        .param pmc array :slurpy
        .return (array)
.end

.sub test_tail
        ## Note that these objects are only referenced by this context.
        $P60 = new Integer
        $P60 = 99
        $P61 = new Integer
        $P61 = 100
        .return list($P60, $P61)
.end

.sub test :main
        test_tail()
        print "Done.\n"
.end

Reply via email to