@@ -1265,41 +1265,16 @@ static mut WP_MYSQL_NATIVE_AST_HANDLERS_PATCHED: bool = false;
12651265/// or change refcounts, so we deliberately do *not* call `set_object`
12661266/// (which addrefs); we set the union directly.
12671267unsafe extern "C" fn ast_get_gc (
1268- object : * mut zend_object ,
1268+ _object : * mut zend_object ,
12691269 table : * mut * mut zval ,
12701270 n : * mut std:: os:: raw:: c_int ,
12711271) -> * mut HashTable {
1272+ // DEBUG: report no outgoing references at all. If this prevents the
1273+ // PHPUnit segfault, the bug lives in the trace-zval construction
1274+ // below; if the segfault persists, the bug is in installing the
1275+ // handler itself (e.g., handlers struct in read-only memory).
12721276 * table = std:: ptr:: null_mut ( ) ;
12731277 * n = 0 ;
1274-
1275- let Some ( ast) = ext_php_rs:: types:: ZendClassObject :: < WpMySqlNativeAst > :: from_zend_obj ( & * object)
1276- . and_then ( |z| z. obj . as_ref ( ) )
1277- else {
1278- return std:: ptr:: null_mut ( ) ;
1279- } ;
1280-
1281- let Ok ( cache) = ast. node_cache . try_borrow ( ) else {
1282- return std:: ptr:: null_mut ( ) ;
1283- } ;
1284- let Ok ( mut trace) = ast. gc_trace . try_borrow_mut ( ) else {
1285- return std:: ptr:: null_mut ( ) ;
1286- } ;
1287-
1288- trace. clear ( ) ;
1289- trace. reserve ( cache. len ( ) ) ;
1290- for boxed in cache. values ( ) {
1291- // Build a zval pointing at the cached wrapper without bumping
1292- // refcount — the GC scan just enumerates outgoing references;
1293- // mutating refcounts here would un-balance the collector's
1294- // accounting.
1295- let mut zv: zval = std:: mem:: zeroed ( ) ;
1296- zv. value . obj = ( boxed. as_ref ( ) as * const ZendObject ) as * mut zend_object as * mut _ ;
1297- zv. u1 . type_info = PHP_IS_OBJECT_EX ;
1298- trace. push ( zv) ;
1299- }
1300-
1301- * table = trace. as_mut_ptr ( ) ;
1302- * n = trace. len ( ) as std:: os:: raw:: c_int ;
13031278 std:: ptr:: null_mut ( )
13041279}
13051280
0 commit comments