Skip to content

Explicitly print reference wrappers in debug_zval_dump() #6750

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 1 commit 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
36 changes: 27 additions & 9 deletions ext/mysqli/tests/mysqli_result_references.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -87,51 +87,69 @@ array(7) refcount(2){
[0]=>
array(2) refcount(1){
["id"]=>
int(1)
reference refcount(1) {
int(1)
}
["label"]=>
string(1) "a" refcount(%d)
}
[1]=>
array(2) refcount(1){
["id"]=>
int(2)
reference refcount(1) {
int(2)
}
["label"]=>
string(1) "b" refcount(%d)
}
[2]=>
array(2) refcount(1){
["id"]=>
int(1)
reference refcount(1) {
int(1)
}
["label"]=>
string(1) "a" refcount(%d)
}
[3]=>
array(2) refcount(1){
["id"]=>
int(2)
reference refcount(1) {
int(2)
}
["label"]=>
string(1) "b" refcount(%d)
}
[4]=>
array(3) refcount(1){
["id"]=>
&int(3)
reference refcount(2) {
int(3)
}
["label"]=>
string(1) "a" refcount(%d)
["id2"]=>
&int(3)
reference refcount(2) {
int(3)
}
}
[5]=>
array(3) refcount(1){
["id"]=>
&int(4)
reference refcount(2) {
int(4)
}
["label"]=>
string(1) "b" refcount(%d)
["id2"]=>
&int(4)
reference refcount(2) {
int(4)
}
}
[6]=>
&object(mysqli_result)#%d (0) refcount(%d){
reference refcount(2) {
object(mysqli_result)#2 (0) refcount(1){
}
}
}
array(1) refcount(2){
Expand Down
34 changes: 24 additions & 10 deletions ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ array(1) refcount(%d){
[0]=>
array(4) refcount(%d){
["row_ref"]=>
&NULL
reference refcount(2) {
NULL
}
["row_copy"]=>
array(2) refcount(1){
["id"]=>
Expand All @@ -64,7 +66,9 @@ array(1) refcount(%d){
string(1) "a" interned
}
["id_ref"]=>
string(1) "1" interned
reference refcount(1) {
string(1) "1" interned
}
["id_copy"]=>
string(1) "1" interned
}
Expand All @@ -73,7 +77,9 @@ array(2) refcount(%d){
[0]=>
array(4) refcount(%d){
["row_ref"]=>
&NULL
reference refcount(2) {
NULL
}
["row_copy"]=>
array(2) refcount(%d){
["id"]=>
Expand All @@ -82,18 +88,24 @@ array(2) refcount(%d){
string(1) "a" interned
}
["id_ref"]=>
string(1) "1" interned
reference refcount(1) {
string(1) "1" interned
}
["id_copy"]=>
string(1) "1" interned
}
[1]=>
array(5) refcount(%d){
["row_ref"]=>
&array(2) refcount(%d){
["id"]=>
&string(1) "2" interned
["label"]=>
string(1) "b" interned
reference refcount(2) {
array(2) refcount(1){
["id"]=>
reference refcount(2) {
string(1) "2" interned
}
["label"]=>
string(1) "b" interned
}
}
["row_copy"]=>
array(2) refcount(%d){
Expand All @@ -103,7 +115,9 @@ array(2) refcount(%d){
string(1) "b" interned
}
["id_ref"]=>
&string(1) "2" interned
reference refcount(2) {
string(1) "2" interned
}
["id_copy"]=>
string(1) "2" interned
["id_copy_mod"]=>
Expand Down
42 changes: 23 additions & 19 deletions ext/standard/tests/general_functions/debug_zval_dump_o.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -345,26 +345,30 @@ object(object_class)#%d (7) refcount(%d){
["object_class1"]=>
*RECURSION*
["obj"]=>
&object(object_class)#%d (7) refcount(%d){
["value1"]=>
int(5)
["value2":"object_class":private]=>
int(10)
["value3":protected]=>
int(20)
["value4"]=>
int(30)
["array_var"]=>
array(2) refcount(%d){
["key1"]=>
int(1)
["key2 "]=>
int(3)
reference refcount(2) {
object(object_class)#8 (7) refcount(2){
["value1"]=>
int(5)
["value2":"object_class":private]=>
int(10)
["value3":protected]=>
int(20)
["value4"]=>
int(30)
["array_var"]=>
array(2) refcount(7){
["key1"]=>
int(1)
["key2 "]=>
int(3)
}
["object_class1"]=>
*RECURSION*
["obj"]=>
reference refcount(2) {
*RECURSION*
}
}
["object_class1"]=>
*RECURSION*
["obj"]=>
*RECURSION*
}
}
Done
46 changes: 46 additions & 0 deletions ext/standard/tests/general_functions/debug_zval_dump_refs.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--TEST--
References in debug_zval_dump()
--FILE--
<?php

$r = 1;
$a = [&$r];
debug_zval_dump($a);
$a[] =& $r;
debug_zval_dump($a);
unset($a[1]);
debug_zval_dump($a);
unset($r);
// rc=1 singleton ref remains
debug_zval_dump($a);

?>
--EXPECT--
array(1) refcount(2){
[0]=>
reference refcount(2) {
int(1)
}
}
array(2) refcount(2){
[0]=>
reference refcount(3) {
int(1)
}
[1]=>
reference refcount(3) {
int(1)
}
}
array(1) refcount(2){
[0]=>
reference refcount(2) {
int(1)
}
}
array(1) refcount(2){
[0]=>
reference refcount(1) {
int(1)
}
}
35 changes: 17 additions & 18 deletions ext/standard/var.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
{
HashTable *myht = NULL;
zend_string *class_name;
int is_ref = 0;
zend_ulong index;
zend_string *key;
zval *val;
Expand All @@ -279,25 +278,24 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
php_printf("%*c", level - 1, ' ');
}

again:
switch (Z_TYPE_P(struc)) {
case IS_FALSE:
php_printf("%sbool(false)\n", COMMON);
PUTS("bool(false)\n");
break;
case IS_TRUE:
php_printf("%sbool(true)\n", COMMON);
PUTS("bool(true)\n");
break;
case IS_NULL:
php_printf("%sNULL\n", COMMON);
PUTS("NULL\n");
break;
case IS_LONG:
php_printf("%sint(" ZEND_LONG_FMT ")\n", COMMON, Z_LVAL_P(struc));
php_printf("int(" ZEND_LONG_FMT ")\n", Z_LVAL_P(struc));
break;
case IS_DOUBLE:
php_printf_unchecked("%sfloat(%.*H)\n", COMMON, (int) PG(serialize_precision), Z_DVAL_P(struc));
php_printf_unchecked("float(%.*H)\n", (int) PG(serialize_precision), Z_DVAL_P(struc));
break;
case IS_STRING:
php_printf("%sstring(%zd) \"", COMMON, Z_STRLEN_P(struc));
php_printf("string(%zd) \"", Z_STRLEN_P(struc));
PHPWRITE(Z_STRVAL_P(struc), Z_STRLEN_P(struc));
if (Z_REFCOUNTED_P(struc)) {
php_printf("\" refcount(%u)\n", Z_REFCOUNT_P(struc));
Expand All @@ -318,9 +316,9 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
count = zend_hash_num_elements(myht);
if (Z_REFCOUNTED_P(struc)) {
/* -1 because of ADDREF above. */
php_printf("%sarray(%d) refcount(%u){\n", COMMON, count, Z_REFCOUNT_P(struc) - 1);
php_printf("array(%d) refcount(%u){\n", count, Z_REFCOUNT_P(struc) - 1);
} else {
php_printf("%sarray(%d) interned {\n", COMMON, count);
php_printf("array(%d) interned {\n", count);
}
ZEND_HASH_FOREACH_KEY_VAL(myht, index, key, val) {
zval_array_element_dump(val, index, key, level);
Expand All @@ -345,7 +343,7 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
GC_PROTECT_RECURSION(myht);
}
class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc));
php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc));
php_printf("object(%s)#%d (%d) refcount(%u){\n", ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc));
zend_string_release_ex(class_name, 0);
if (myht) {
ZEND_HASH_FOREACH_KEY_VAL(myht, index, key, val) {
Expand All @@ -372,18 +370,19 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
break;
case IS_RESOURCE: {
const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(struc));
php_printf("%sresource(%d) of type (%s) refcount(%u)\n", COMMON, Z_RES_P(struc)->handle, type_name ? type_name : "Unknown", Z_REFCOUNT_P(struc));
php_printf("resource(%d) of type (%s) refcount(%u)\n", Z_RES_P(struc)->handle, type_name ? type_name : "Unknown", Z_REFCOUNT_P(struc));
break;
}
case IS_REFERENCE:
//??? hide references with refcount==1 (for compatibility)
if (Z_REFCOUNT_P(struc) > 1) {
is_ref = 1;
php_printf("reference refcount(%u) {\n", Z_REFCOUNT_P(struc));
php_debug_zval_dump(Z_REFVAL_P(struc), level + 2);
if (level > 1) {
php_printf("%*c", level - 1, ' ');
}
struc = Z_REFVAL_P(struc);
goto again;
PUTS("}\n");
break;
default:
php_printf("%sUNKNOWN:0\n", COMMON);
PUTS("UNKNOWN:0\n");
break;
}
}
Expand Down