I was playing around a bit with the set_keyed and get_keyed ops and found
 that this:

         new P0, PerlArray
         set I0, 0
 LOOP:   set_keyed P0, I0, I0
         inc I0
         lt I0, 10000, LOOP
         end

 causes Parrot to segfault.

 The culprit appears to be this bit of code in trace_active_PMCs in
 resources.c:

  ----

                  else {
                    /* The only thing left is "buffer of PMCs" */
                    Buffer *trace_buf = current->data;
                    PMC **cur_pmc = trace_buf->bufstart;
                    /* Mark the damn buffer as used! */
                    trace_buf->flags |= BUFFER_live_FLAG;
                    for (i = 0; i < trace_buf->buflen; i++) {
                        if (cur_pmc[i]) {
                            last = mark_used(cur_pmc[i], last);
                        }
                    }
                }

  ----

 The problem is that trace_buf->buflen is the size of the buffer, and
 not the number of PMCs contained in it, so the loop reads out of the
 end of cur_pmc and into garbage data. The patch below fixes this, and
 also adds a test-case to perlarray.t to stop it from coming back.

 Simon


--- resources.c.old     Sat Apr 20 17:55:28 2002
+++ resources.c         Sat Apr 20 17:58:45 2002
@@ -462,9 +462,10 @@
                     /* The only thing left is "buffer of PMCs" */
                     Buffer *trace_buf = current->data;
                     PMC **cur_pmc = trace_buf->bufstart;
+                    UINTVAL no_of_pmcs = trace_buf->buflen / sizeof(PMC*);
                     /* Mark the damn buffer as used! */
                     trace_buf->flags |= BUFFER_live_FLAG;
-                    for (i = 0; i < trace_buf->buflen; i++) {
+                    for (i = 0; i < no_of_pmcs; i++) {
                         if (cur_pmc[i]) {
                             last = mark_used(cur_pmc[i], last);
                         }


--- t/pmc/perlarray.t.old       Sat Apr 20 18:09:16 2002
+++ t/pmc/perlarray.t           Sat Apr 20 18:13:48 2002
@@ -1,6 +1,6 @@
 #! perl -w

-use Parrot::Test tests => 6;
+use Parrot::Test tests => 7;
 use Test::More;

 output_is(<<'CODE', <<'OUTPUT', "size of the array");
@@ -275,4 +275,18 @@
 ok 19
 OUTPUT

+output_is(<<'CODE', <<'OUTPUT', "Array resizing stress-test");
+        new P0, PerlArray
+        set I0, 0
+LOOP:   set_keyed P0, I0, I0     # set P0[I0], I0
+        inc I0
+        lt I0, 10000, LOOP
+        get_keyed I1, P0, 9999   # set I1, P0[9999]
+        print I1
+        print "\n"
+        end
+CODE
+9999
+OUTPUT
+
 1;

Reply via email to