summaryrefslogtreecommitdiff
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
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
-rw-r--r--Zend/zend_gc.c17
-rw-r--r--Zend/zend_gc.h1
2 files changed, 17 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)) {
diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h
index 84b7ef3208..2eb8ea6ea3 100644
--- a/Zend/zend_gc.h
+++ b/Zend/zend_gc.h
@@ -83,6 +83,7 @@ typedef struct _gc_root_buffer {
typedef struct _zend_gc_globals {
zend_bool gc_enabled;
zend_bool gc_active;
+ zend_bool gc_full;
gc_root_buffer *buf; /* preallocated arrays of buffers */
gc_root_buffer roots; /* list of possible roots of cycles */