Laruence,
Sorry, but I don't this this explain is right. > > if there is more than one refcount to a zval, then it should never be > freed > > and if a zval is freed, then it must also be removed from the gc roots. > The point here is that the GC is run *while* the zval is being freed. Check out the backtrace here: https://bugs.php.net/bug.php?id=64827 , specifically zval pointer 0x272afb8 It appears 4 times recursively being passed into zend_objects_free_object_storage before the GC is triggered and it segfaults. > according to your explain, the gc segfault while walking through > a hashtable of a object. > Yes, that is what's happening here. zval_mark_grey() is trying to walk through the object's hash table, but the first bucket is already freed, so when it tries to access it bad things happen. > but that doesn't make any sense, since if it segfault in walking, > then it should also segfault when trying to free the hash table later > while dtor the object. > That's the point. The dtor is already happening on that object when the GC tries to run over it again. > disable GC in shutdown is okey for me. but that is just try to > cover the bug somewhere in the refcount handler.. not the right fix. > Looking back through, we still have the problem where we can't null out the zval before destructing the object (like we do with arrays) to prevent this. That's why I suggested one alternative would be to modify zend_objects_store_del_ref_by_handle_ex to also accept the zval, so it can be nulled if the object is going to be freed. However, we could set the object's bucket to invalid in the delref handler before we call free_storage. And then modify the GC to check for a valid bucket... I'll try that patch today to see if it solves the original issue (as it shouldn't result in an API change either)... Thanks for the thoughts... Anthony