From 5cf6428d0fa8af2a3f024d59760b2e89dfd4cadc Mon Sep 17 00:00:00 2001 From: root Date: Sat, 12 Mar 2016 22:42:11 -0500 Subject: [PATCH 1/4] Fix seg fault in apache2 + php7 on shutdown, check if store is null --- wr_store.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wr_store.c b/wr_store.c index b969649..95ca3e7 100644 --- a/wr_store.c +++ b/wr_store.c @@ -55,6 +55,7 @@ void wr_store_destroy() /* {{{ */ void wr_store_tracked_object_dtor(zend_object *ref_obj) /* {{{ */ { wr_store *store = WR_G(store); + if (!store) return; zend_object_dtor_obj_t orig_dtor = zend_hash_index_find_ptr(&store->old_dtors, (ulong)ref_obj->handlers); ulong handle_key = ref_obj->handle; wr_ref_list *list_entry; From 95aee57a42adc9adb7a85a21b00f0b8a36e34722 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Mar 2016 20:06:38 -0400 Subject: [PATCH 2/4] The issue with PHP7 + Apache2 seg fault is properly addressed and tested. Explicitly restoring the dtor handlers on shutdown --- wr_store.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/wr_store.c b/wr_store.c index 95ca3e7..05bbc03 100644 --- a/wr_store.c +++ b/wr_store.c @@ -13,6 +13,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Etienne Kneuss | + | Fix for PHP7+Apache2: CommerceByte Consulting | +----------------------------------------------------------------------+ */ @@ -38,9 +39,24 @@ void wr_store_init() /* {{{ */ WR_G(store) = store; } /* }}} */ +/* See comment in wr_store_destroy */ +int wr_store_dtor_restore(zend_object_dtor_obj_t *val,int arg_num, va_list arg_list, zend_hash_key *key) +{ + + ((zend_object_handlers *) key->h)->dtor_obj = *val; + return ZEND_HASH_APPLY_REMOVE; +} + void wr_store_destroy() /* {{{ */ { wr_store *store = WR_G(store); + + /* + jim@commercebyte.com - + Explicitly restore the dtor handlers + Not doing so causes a disaster in PHP7 + Apache2 lib environment + */ + zend_hash_apply_with_arguments(&store->old_dtors, wr_store_dtor_restore, 0); zend_hash_destroy(&store->old_dtors); zend_hash_destroy(&store->objs); @@ -50,12 +66,19 @@ void wr_store_destroy() /* {{{ */ WR_G(store) = NULL; } /* }}} */ + + /* This function is invoked whenever an object tracked by a weak ref/map is * destroyed */ void wr_store_tracked_object_dtor(zend_object *ref_obj) /* {{{ */ { wr_store *store = WR_G(store); - if (!store) return; + + if (!store) { + /* Sanity check, should never get here as long as wr_store_dtor_restore() is engaged */ + return; + } + zend_object_dtor_obj_t orig_dtor = zend_hash_index_find_ptr(&store->old_dtors, (ulong)ref_obj->handlers); ulong handle_key = ref_obj->handle; wr_ref_list *list_entry; From 7bf2085a29f184d1b36b57f2424ef414743733e6 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss Date: Tue, 15 Mar 2016 11:09:04 +0100 Subject: [PATCH 3/4] Fix build warnings --- wr_store.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wr_store.c b/wr_store.c index 05bbc03..574e24a 100644 --- a/wr_store.c +++ b/wr_store.c @@ -40,10 +40,11 @@ void wr_store_init() /* {{{ */ } /* }}} */ /* See comment in wr_store_destroy */ -int wr_store_dtor_restore(zend_object_dtor_obj_t *val,int arg_num, va_list arg_list, zend_hash_key *key) +int wr_store_dtor_restore(zval *val,int arg_num, va_list arg_list, zend_hash_key *key) { + zend_object_dtor_obj_t *dtor = (zend_object_dtor_obj_t*) Z_PTR_P(val); - ((zend_object_handlers *) key->h)->dtor_obj = *val; + ((zend_object_handlers *) key->h)->dtor_obj = *dtor; return ZEND_HASH_APPLY_REMOVE; } From c6f1d1109ba3f7553d74e706fcc318f877c33273 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 15 Mar 2016 10:47:01 -0400 Subject: [PATCH 4/4] wr_store.c: old_dtors it actually holds zend_object_dtor_obj_t's, not zval's, so Z_PTR_P() didn't do any good --- wr_store.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wr_store.c b/wr_store.c index 574e24a..4185b0e 100644 --- a/wr_store.c +++ b/wr_store.c @@ -42,7 +42,7 @@ void wr_store_init() /* {{{ */ /* See comment in wr_store_destroy */ int wr_store_dtor_restore(zval *val,int arg_num, va_list arg_list, zend_hash_key *key) { - zend_object_dtor_obj_t *dtor = (zend_object_dtor_obj_t*) Z_PTR_P(val); + zend_object_dtor_obj_t *dtor = (zend_object_dtor_obj_t*) val; ((zend_object_handlers *) key->h)->dtor_obj = *dtor; return ZEND_HASH_APPLY_REMOVE;