Commit:    3c1888f58468ff0fd7f6c20f3fd7701ed7273647
Author:    Dmitry Stogov <dmi...@zend.com>         Thu, 29 Nov 2012 13:06:12 
+0400
Parents:   bc7f2b5f413c14e8b8b28660095ee9f1c7793d06
Branches:  PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=3c1888f58468ff0fd7f6c20f3fd7701ed7273647

Log:
Fixed bug #63635 (Segfault in gc_collect_cycles)

Bugs:
https://bugs.php.net/63635

Changed paths:
  A  Zend/tests/bug63635.phpt
  M  Zend/zend_gc.c


Diff:
diff --git a/Zend/tests/bug63635.phpt b/Zend/tests/bug63635.phpt
new file mode 100644
index 0000000..6f6fc6a
--- /dev/null
+++ b/Zend/tests/bug63635.phpt
@@ -0,0 +1,58 @@
+--TEST--
+Bug #63635 (Segfault in gc_collect_cycles)
+--FILE--
+<?php
+class Node {
+       public $parent = NULL;
+       public $childs = array();
+       
+       function __construct(Node $parent=NULL) {
+               if ($parent) {
+                       $parent->childs[] = $this;
+               }
+               $this->childs[] = $this;
+       }
+       
+       function __destruct() {
+               $this->childs = NULL;
+       }       
+}
+
+define("MAX", 16);
+
+for ($n = 0; $n < 20; $n++) {
+       $top = new Node();
+       for ($i=0 ; $i<MAX ; $i++) {
+               $ci = new Node($top);
+               for ($j=0 ; $j<MAX ; $j++) {
+                       $cj = new Node($ci);
+                       for ($k=0 ; $k<MAX ; $k++) {
+                               $ck = new Node($cj);
+                       }
+               }
+       }
+       echo "$n\n";
+}
+echo "ok\n";
+--EXPECT--
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+ok
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c
index 84a99c1..e877eab 100644
--- a/Zend/zend_gc.c
+++ b/Zend/zend_gc.c
@@ -644,7 +644,8 @@ tail_call:
                        struct _store_object *obj = 
&EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj;
 
                        if (obj->buffered == (gc_root_buffer*)GC_WHITE) {
-                               GC_SET_BLACK(obj->buffered);
+                               /* PURPLE instead of BLACK to prevent buffering 
in nested gc calls */
+                               GC_SET_PURPLE(obj->buffered);
 
                                if 
(EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                                             (get_gc = Z_OBJ_HANDLER_P(pz, 
get_gc)) != NULL)) {
@@ -715,7 +716,8 @@ static void zobj_collect_white(zval *pz TSRMLS_DC)
                struct _store_object *obj = 
&EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj;
 
                if (obj->buffered == (gc_root_buffer*)GC_WHITE) {
-                       GC_SET_BLACK(obj->buffered);
+                       /* PURPLE instead of BLACK to prevent buffering in 
nested gc calls */
+                       GC_SET_PURPLE(obj->buffered);
 
                        if 
(EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                                     (get_gc = Z_OBJ_HANDLER_P(pz, get_gc)) != 
NULL)) {


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to