summaryrefslogtreecommitdiff
path: root/Zend/zend_gc.c
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2014-09-13 01:52:47 +0800
committerXinchen Hui <laruence@php.net>2014-09-13 01:55:49 +0800
commit78ce2557f547b5638e0e3c4930cc035f82186427 (patch)
tree51fdfd7931dc9e418f03740555eb718a9ff105e6 /Zend/zend_gc.c
parent4db2181d4e5fad2ece558dcd72e4842e4f5b8d70 (diff)
downloadphp-git-78ce2557f547b5638e0e3c4930cc035f82186427.tar.gz
Finally!!! Fixed segfault in GC
this must not be the final fix, but let's stop the segfault first and use this to indicate where the problem is. reproduced by phpspec
Diffstat (limited to 'Zend/zend_gc.c')
-rw-r--r--Zend/zend_gc.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c
index adc02a3eb0..590b08a214 100644
--- a/Zend/zend_gc.c
+++ b/Zend/zend_gc.c
@@ -492,8 +492,11 @@ tail_call:
} else if (GC_G(first_unused) != GC_G(last_unused)) {
buf = GC_G(first_unused);
GC_G(first_unused)++;
+ } else {
+ /* TODO: find a perfect way to handle such case */
+ GC_G(gc_full) = 1;
}
- /* TODO: what should we do if we don't have room ??? */
+
if (buf) {
buf->ref = ref;
buf->next = GC_G(roots).next;
@@ -609,6 +612,18 @@ static int gc_collect_roots(TSRMLS_D)
}
current = current->next;
}
+
+ if (GC_G(gc_full) == 1) {
+ current = GC_G(roots).next;
+ while (current != &GC_G(roots)) {
+ GC_SET_ADDRESS(GC_INFO(current->ref), 0);
+ GC_SET_BLACK(GC_INFO(current->ref));
+ current = current->next;
+ }
+ gc_reset(TSRMLS_CC);
+ return 0;
+ }
+
/* relink remaining roots into list to free */
if (GC_G(roots).next != &GC_G(roots)) {
if (GC_G(to_free).next == &GC_G(to_free)) {