Skip to content

fix segfault in wr_store_tracked_object_dtor #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ configure
config.log
config.guess
run-tests.php
tmp-php.ini
config.h
config.sub
ltmain.sh
ltmain.sh.backup
Makefile.fragments
Makefile.objects
modules
Expand Down
9 changes: 8 additions & 1 deletion tests/weakref_007.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ Weakref: Destroying the weakref and its object after a fatal error
}
?>
--EXPECTF--
Destroy A
Destroy B
bool(false)

Fatal error: Call to undefined function crash() in %s on line %d
Fatal error: Uncaught Error: Call to undefined function crash() in %s:%d
Stack trace:
#0 %s(%d): doit()
#1 {main}
thrown in %s on line %d
Exit: 255
16 changes: 10 additions & 6 deletions wr_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,23 @@ void wr_store_tracked_object_dtor(zend_object *ref_obj) /* {{{ */
wr_store *store = WR_G(store);

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;

/* Original dtor has been called, we invalidate the necessary weakrefs: */
orig_dtor(ref_obj);

wr_ref_list *list_entry;
if ((list_entry = zend_hash_index_find_ptr(&store->objs, ref_obj->handle)) != NULL) {
list_entry = zend_hash_index_find_ptr(&store->objs, handle_key);
if (list_entry) {
/* Invalidate wrefs_head while dtoring, to prevent detach on same wr */
zend_hash_index_del(&store->objs, ref_obj->handle);
zend_hash_index_del(&store->objs, handle_key);

while (list_entry != NULL) {
do {
wr_ref_list *next = list_entry->next;
list_entry->dtor(list_entry->wref_obj, ref_obj);
efree(list_entry);
list_entry = next;
}
} while (list_entry);
}
}
/* }}} */
Expand Down Expand Up @@ -135,8 +137,10 @@ void wr_store_untrack(zend_object *wref_obj, zend_object *ref_obj) /* {{{ */

if (prev) {
prev->next = cur->next;
} else {
} else if (cur->next) {
zend_hash_index_update_ptr(&store->objs, ref_obj->handle, cur->next);
} else {
zend_hash_index_del(&store->objs, (ulong)ref_obj->handle);
}

efree(cur);
Expand Down