Skip to content

Commit 5da591c

Browse files
committed
Fixed bug #77345 (Stack Overflow caused by circular reference in garbage collection)
1 parent 59e76ec commit 5da591c

File tree

4 files changed

+333
-90
lines changed

4 files changed

+333
-90
lines changed

NEWS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ PHP NEWS
66
. Fixed bug #77660 (Segmentation fault on break 2147483648). (Laruence)
77
. Fixed bug #77652 (Anonymous classes can lose their interface information).
88
(Nikita)
9-
9+
. Fixed bug #77345 (Stack Overflow caused by circular reference in garbage
10+
collection). (Alexandru Patranescu, Nikita, Dmitry)
1011
- Apache2Handler:
1112
. Fixed bug #77648 (BOM in sapi/apache2handler/php_functions.c). (cmb)
1213

Zend/tests/bug77345_gc_1.phpt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
Bug #77345 (Segmentation faults stack overflow in cyclic garbage collector) (Bug #77427)
3+
--INI--
4+
zend.enable_gc = 1
5+
--FILE--
6+
<?php
7+
8+
class Node
9+
{
10+
/** @var Node */
11+
public $previous;
12+
/** @var Node */
13+
public $next;
14+
}
15+
16+
var_dump(gc_enabled());
17+
var_dump('start');
18+
19+
$firstNode = new Node();
20+
$firstNode->previous = $firstNode;
21+
$firstNode->next = $firstNode;
22+
23+
$circularDoublyLinkedList = $firstNode;
24+
25+
for ($i = 0; $i < 200000; $i++) {
26+
$currentNode = $circularDoublyLinkedList;
27+
$nextNode = $circularDoublyLinkedList->next;
28+
29+
$newNode = new Node();
30+
31+
$newNode->previous = $currentNode;
32+
$currentNode->next = $newNode;
33+
$newNode->next = $nextNode;
34+
$nextNode->previous = $newNode;
35+
36+
$circularDoublyLinkedList = $nextNode;
37+
}
38+
var_dump('end');
39+
--EXPECT--
40+
bool(true)
41+
string(5) "start"
42+
string(3) "end"

Zend/tests/bug77345_gc_2.phpt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--TEST--
2+
Bug #77345 (Segmentation faults stack overflow in cyclic garbage collector) (Bug #77427)
3+
--INI--
4+
zend.enable_gc = 1
5+
--FILE--
6+
<?php
7+
8+
class Node
9+
{
10+
/** @var Node */
11+
public $previous;
12+
/** @var Node */
13+
public $next;
14+
}
15+
16+
var_dump(gc_enabled());
17+
var_dump('start');
18+
19+
function xxx() {
20+
$firstNode = new Node();
21+
$firstNode->previous = $firstNode;
22+
$firstNode->next = $firstNode;
23+
24+
$circularDoublyLinkedList = $firstNode;
25+
26+
for ($i = 0; $i < 300000; $i++) {
27+
$currentNode = $circularDoublyLinkedList;
28+
$nextNode = $circularDoublyLinkedList->next;
29+
30+
$newNode = new Node();
31+
32+
$newNode->previous = $currentNode;
33+
$currentNode->next = $newNode;
34+
$newNode->next = $nextNode;
35+
$nextNode->previous = $newNode;
36+
37+
$circularDoublyLinkedList = $nextNode;
38+
}
39+
}
40+
41+
xxx();
42+
gc_collect_cycles();
43+
44+
var_dump('end');
45+
--EXPECT--
46+
bool(true)
47+
string(5) "start"
48+
string(3) "end"

0 commit comments

Comments
 (0)