Skip to content
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

Assertion failure for TRACK_VARS_SERVER #15905

Closed
YuanchengJiang opened this issue Sep 16, 2024 · 3 comments
Closed

Assertion failure for TRACK_VARS_SERVER #15905

YuanchengJiang opened this issue Sep 16, 2024 · 3 comments

Comments

@YuanchengJiang
Copy link

Description

The following code:

To reproduce:

php -d "variables_order=E" -d "auto_globals_jit=0"

Resulted in this output:

/php-src/Zend/zend_hash.c:825: _zend_hash_add_or_update_i: Assertion `(zend_gc_refcount(&(ht)->gc) == 1) || ((ht)->u.flags & (1<<6))' failed.
Aborted (core dumped)

PHP Version

PHP 8.4.0-dev

Operating System

ubuntu 22.04

@cmb69 cmb69 changed the title Core dumped with -d "variables_order=E" -d "auto_globals_jit=0" Assertion failure with -d "variables_order=E" -d "auto_globals_jit=0" Sep 16, 2024
@cmb69
Copy link
Member

cmb69 commented Sep 16, 2024

Good finding, @YuanchengJiang!

Relevant:

/* TODO: TRACK_VARS_SERVER is modified in a number of places (e.g. phar) past this point,
* where rc>1 due to the $_SERVER global. Ideally this shouldn't happen, but for now we
* ignore this issue, as it would probably require larger changes. */
HT_ALLOW_COW_VIOLATION(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]));

However, with -d variables_order=E -d auto_globals_jit=0, PG(http_globals)[TRACK_VARS_SERVER]) is not properly initialized, so it looses the HASH_FLAG_ALLOW_COW_VIOLATION flag. A possible fix could be to initialize the hash table right away for this code path, i.e.:

 main/php_variables.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/main/php_variables.c b/main/php_variables.c
index c3b773516e..7569fd43e9 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -893,6 +893,7 @@ static bool php_auto_globals_create_server(zend_string *name)
 	} else {
 		zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_SERVER]);
 		array_init(&PG(http_globals)[TRACK_VARS_SERVER]);
+		zend_hash_real_init_mixed(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]));
 	}
 
 	check_http_proxy(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]));

@nielsdos
Copy link
Member

Reminds me of #13013 ...
Anyway, I think your patch is fine @cmb69

@cmb69 cmb69 self-assigned this Sep 16, 2024
cmb69 added a commit to cmb69/php-src that referenced this issue Sep 16, 2024
When the superglobals are eagerly initialized, but "S" is not contained
in `variables_order`, `TRACK_VARS_SERVER` is created as empty array
with refcount > 1.  Since this hash table may later be modified, a flag
is set which allows such COW violations for assertions.  However, when
`register_argc_argv` is on, the so far uninitialized hash table is
updated with `argv`, what causes the hash table to be initialized, what
drops the allow-COW-violations flag.  The following update with `argc`
then triggers a refcount violation assertion.

Since we consider `HT_ALLOW_COW_VIOLATION` a hack, we do not want to
keep the flag during hash table initialization, so we initialize the
hash table right away after creation for this code path.
@cmb69 cmb69 changed the title Assertion failure with -d "variables_order=E" -d "auto_globals_jit=0" Assertion failure for TRACK_VARS_SERVER Sep 16, 2024
@cmb69 cmb69 linked a pull request Sep 16, 2024 that will close this issue
@cmb69
Copy link
Member

cmb69 commented Sep 16, 2024

Reminds me of #13013 ...

Fascinating!

@cmb69 cmb69 closed this as completed in 87d59d7 Sep 26, 2024
cmb69 added a commit that referenced this issue Sep 26, 2024
* PHP-8.2:
  Fix GH-15905: Assertion failure for TRACK_VARS_SERVER
cmb69 added a commit that referenced this issue Sep 26, 2024
* PHP-8.3:
  Fix GH-15905: Assertion failure for TRACK_VARS_SERVER
cmb69 added a commit that referenced this issue Sep 26, 2024
* PHP-8.4:
  Fix GH-15905: Assertion failure for TRACK_VARS_SERVER
jorgsowa pushed a commit to jorgsowa/php-src that referenced this issue Oct 1, 2024
When the superglobals are eagerly initialized, but "S" is not contained
in `variables_order`, `TRACK_VARS_SERVER` is created as empty array
with refcount > 1.  Since this hash table may later be modified, a flag
is set which allows such COW violations for assertions.  However, when
`register_argc_argv` is on, the so far uninitialized hash table is
updated with `argv`, what causes the hash table to be initialized, what
drops the allow-COW-violations flag.  The following update with `argc`
then triggers a refcount violation assertion.

Since we consider `HT_ALLOW_COW_VIOLATION` a hack, we do not want to
keep the flag during hash table initialization, so we initialize the
hash table right away after creation for this code path.

Closes phpGH-15930.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants