Skip to content

Commit 36abf37

Browse files
committed
dd_library_loader: prevent ddtrace zend ext shutdown run AFTER ddtrace is dlclose()d
1 parent f917268 commit 36abf37

2 files changed

Lines changed: 15 additions & 6 deletions

File tree

loader/dd_library_loader.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -998,15 +998,24 @@ static int ddloader_zend_extension_startup(zend_extension *ext) {
998998

999999
static void ddloader_zend_extension_shutdown(zend_extension *ext) {
10001000
UNUSED(ext);
1001-
/* Close injected extension handles first (ddtrace.so, ddappsec.so, etc.),
1002-
* then libddtrace_php.so which they may depend on. */
10031001
for (unsigned int i = 0; i < sizeof(ddloader_injected_ext_config) / sizeof(ddloader_injected_ext_config[0]); ++i) {
1004-
if (ddloader_injected_ext_config[i].so_handle) {
1005-
DL_UNLOAD(ddloader_injected_ext_config[i].so_handle);
1006-
ddloader_injected_ext_config[i].so_handle = NULL;
1002+
// Set the handle on the zend_extension so that zend_extension_dtor()
1003+
// will call DL_UNLOAD after this shutdown callback runs. Zend extension
1004+
// shutdown callbacks are run in the same order (not reverse) as they
1005+
// were loaded. So the callbacks for ddtrace/appsec/profiling will run
1006+
// AFTER this callback.
1007+
injected_ext *ext_config = &ddloader_injected_ext_config[i];
1008+
if (ext_config->so_handle) {
1009+
zend_extension *zend_ext = zend_get_extension(ext_config->ext_name);
1010+
if (zend_ext) {
1011+
zend_ext->handle = ext_config->so_handle;
1012+
}
1013+
ext_config->so_handle = NULL;
10071014
}
10081015
}
1016+
10091017
if (libddtrace_php_handle) {
1018+
// This still won't unload it
10101019
DL_UNLOAD(libddtrace_php_handle);
10111020
libddtrace_php_handle = NULL;
10121021
}

loader/php_dd_library_loader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ typedef struct _injected_ext {
6363
const zend_function_entry *orig_module_functions;
6464
int module_number;
6565
char *version;
66-
void *so_handle; // dlopen handle of the loaded .so; closed in ddloader_zend_extension_shutdown
66+
void *so_handle; // dlopen handle of the loaded .so
6767

6868
// phpinfo data
6969
bool injection_success;

0 commit comments

Comments
 (0)