com php-src: Finally!!! Fixed segfault in GC: Zend/zend_gc. c Zend/zend_gc.h
| From: | Xinchen Hui | Date: | Fri, 12 Sep 2014 17:55:49 +0000 |
| Subject: | com php-src: Finally!!! Fixed segfault in GC: Zend/zend_gc. c Zend/zend_gc.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-81521@lists.php.net to get a copy of this message | ||
Commit: 78ce2557f547b5638e0e3c4930cc035f82186427
Author: Xinchen Hui <laruence@php.net> Sat, 13 Sep 2014 01:52:47 +0800
Parents: 4db2181d4e5fad2ece558dcd72e4842e4f5b8d70
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=78ce2557f547b5638e0e3c4930cc035f82186427
Log:
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
Changed paths:
M Zend/zend_gc.c
M Zend/zend_gc.h
Diff:
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c
index adc02a3..590b08a 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 84b7ef3..2eb8ea6 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 */