From: Xinchen Hui Date: Fri, 12 Sep 2014 17:52:47 +0000 (+0800) Subject: Finally!!! Fixed segfault in GC X-Git-Tag: PRE_NATIVE_TLS_MERGE~150^2~18^2~48 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=78ce2557f547b5638e0e3c4930cc035f82186427;p=php 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 --- 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 */