-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Fix unregistering ini entries of dynamically loaded extension #8435
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
Conversation
4e62576
to
31c303f
Compare
This is supposed to fix #8185, I think. |
e9c08ee
to
45c10f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR! Before more detailed review, we need to clarify whether this constitutes an ABI break (if so, we cannot target any of the stable PHP versions).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this looks good to me, but I left some style nits.
ext/dl_test/.gitignore
Outdated
@@ -0,0 +1,41 @@ | |||
*.lo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this file? Isn't that already handled by .gitignore in the root?
ext/dl_test/dl_test.c
Outdated
| obtain it through the world-wide-web, please send a note to | | ||
| [email protected] so we can mail you a copy immediately. | | ||
+----------------------------------------------------------------------+ | ||
| Author: | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should add yourself as author.
ext/dl_test/php_dl_test.h
Outdated
extern zend_module_entry dl_test_module_entry; | ||
# define phpext_dl_test_ptr &dl_test_module_entry | ||
|
||
# define PHP_DL_TEST_VERSION "0.1.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the point in having an own version for a bundled extension; consider to use PHP_VERSION
instead of some hard-coded value.
ext/dl_test/tests/skip.inc
Outdated
// Check that the dl_test extension is built. We don't use the --EXTENSIONS-- | ||
// section because we want to load the extension with dl(). | ||
|
||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { | |
if (PHP_OS_FAMILY === 'Windows') { |
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { | ||
$path = ini_get('extension_dir') . DIRECTORY_SEPARATOR . 'php_dl_test.dll'; | ||
} else { | ||
$path = ini_get('extension_dir') . DIRECTORY_SEPARATOR . 'dl_test.so'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have to cater to macOS which uses .dylib
as far as I know?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked because I was not sure. The PHP build appears to generate .so
files. The CI looks ok too (no mention of skipping or failing these tests).
--TEST-- | ||
dl(): Loaded extensions properly unregister their ini settings | ||
--SKIPIF-- | ||
<?php include __DIR__ . "/../../../dl_test/tests/skip.inc"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I very much prefer to explicitly have the closing PHP tags in .phpt files, so that syntax highlighting works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't they also required for another reason? But yes I agree adding the closing tags is better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. The sections containing PHP code are extracted to temporary files, so closing tags are not strictly needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me personally it's because I like to be able to run tests quickly without invoking run-tests, by just doing php thetest.phpt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than the PHPT test changes LGTM
--TEST-- | ||
dl(): Loaded extensions properly unregister their ini settings | ||
--SKIPIF-- | ||
<?php include __DIR__ . "/../../../dl_test/tests/skip.inc"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<?php include __DIR__ . "/../../../dl_test/tests/skip.inc"; | |
<?php include dirname(__DIR__, 3) . "/dl_test/tests/skip.inc"; |
Might be 2, not sure of the top of my head.
--TEST-- | ||
dl(): Loaded extensions properly unregister their ini settings | ||
--SKIPIF-- | ||
<?php include __DIR__ . "/../../../dl_test/tests/skip.inc"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't they also required for another reason? But yes I agree adding the closing tags is better
@@ -210,7 +211,10 @@ ZEND_API zend_result zend_register_ini_entries(const zend_ini_entry_def *ini_ent | |||
* lead to death. | |||
*/ | |||
if (directives != EG(ini_directives)) { | |||
ZEND_ASSERT(module_type == MODULE_TEMPORARY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arnaud-lb just stumbled on this when fixing FPM extension loading using php_admin_value[extension]
. It actaully uses php_dl
and initializes permanent module so this is actually not going to work so I had to remove this assertion in #12277 . FPM is single threaded so it should not impact this issue - it just really needs to remove the assertion.
There might be potentially other issues with using dl for permanent modules and it has got some limitation but think the whole concept of using php_dl in FPM is really problematic which will require some bigger changes in FPM to get it rif of it (introduction of pool manager).
Anyway if you see some bigger problem with my change, please comment on that PR.
This fixes a crash involving ZTS and dl().
In ZTS, the global
registered_zend_ini_directives
is copied to a thread-specificEG(ini_entries)
. Extensions loaded withdl()
register their ini entries inEG(ini_entries)
, however they unregister them fromregistered_zend_ini_directives
, which has no effect and leaves the entries inEG(ini_entries)
. This leads to problems when destroyingEG(ini_entries)
later, because it references resources that are already freed.This change ensures that MODULE_TEMPORARY modules will unregister their entries from
EG(ini_entries)
.I added a test extension specifically for the purpose of testing dl(). I could have used the
zend_test
for that, but I felt that with a dedicated extension it would be harder to accidentally nerf/no-op the tests.