You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We are just working on improvement / fix for PHP timer (max execution time) with use of libdispatch: php/php-src#13468 . This is working on CLI but if run on PHP-FPM, which uses a typical process worker (master process creates multiple children), it crashes. After debugging it, we found out that it is due to the fact that Curl, which is loaded in master process, uses SCDynamicStoreCopyProxies which does libdispatch calls. When FPM forks, the code using libdispatch is unable to activate the timer.
I have create a minimal reproducer (just using plain C) which presents the problem and show the crash:
// timer.c can be compiled as// cc -framework Foundation -framework SystemConfiguration -o timer timer.c#include<dispatch/dispatch.h>#include<SystemConfiguration/SCDynamicStoreCopySpecific.h>#include<stdio.h>#include<stdlib.h>#include<sys/wait.h>#include<unistd.h>#include<signal.h>voidtimer_handler(void*ctx)
{
printf("handle\n");
}
voidtimer_cancel(void*ctx)
{
printf("cancel\n");
}
voidsigchld_handler(intsignum) {
intstatus;
pid_tpid;
while ((pid=waitpid(-1, &status, WNOHANG)) >0) {
if (WIFEXITED(status)) {
printf("Child %d exited with status %d\n", pid, WEXITSTATUS(status));
} elseif (WIFSIGNALED(status)) {
printf("Child %d killed by signal %d\n", pid, WTERMSIG(status));
}
}
}
intmain()
{
// if SCDynamicStoreCopyProxies is in parent, it crashesCFDictionaryRefdict=SCDynamicStoreCopyProxies(NULL);
if (dict)
CFRelease(dict);
signal(SIGCHLD, sigchld_handler);
intpid=fork();
if (pid==0) {
// if SCDynamicStoreCopyProxies is in the child, it works// CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);// if(dict)// CFRelease(dict);// using global queue crashes which could be expected// dispatch_queue_global_t queue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);// but custom queue which should not have global state also crashesdispatch_queue_attr_tattr=dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_UTILITY, 0);
dispatch_queue_tqueue=dispatch_queue_create("net.php.zend_max_execution_timer", attr);
dispatch_source_ttimer=dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (timer==NULL) {
printf("timer is null\n");
return1;
}
dispatch_source_set_event_handler_f(timer, timer_handler);
dispatch_source_set_cancel_handler_f(timer, timer_cancel);
dispatch_source_set_timer(
timer,
dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC),
2*NSEC_PER_SEC,
0
);
dispatch_activate(timer);
sleep(10);
} elseif (pid>0) {
printf("created child %d\n", pid);
intstatus;
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
printf("Child exited with status %d\n", WEXITSTATUS(status));
} elseif (WIFSIGNALED(status)) {
printf("Child killed by signal %d\n", WTERMSIG(status));
}
printf("finishing\n");
} else {
printf("fork error\n");
}
return0;
}
When this is run, it will show that child crashes (segfault) due to accessing invalid memory which happens during dispatch_activate.
Is this issue known and is libdispatch not usable after the fork? Potentially is there anything that can be done to get around this issue (except not doing fork)?
The text was updated successfully, but these errors were encountered:
We are just working on improvement / fix for PHP timer (max execution time) with use of libdispatch: php/php-src#13468 . This is working on CLI but if run on PHP-FPM, which uses a typical process worker (master process creates multiple children), it crashes. After debugging it, we found out that it is due to the fact that Curl, which is loaded in master process, uses SCDynamicStoreCopyProxies which does libdispatch calls. When FPM forks, the code using libdispatch is unable to activate the timer.
I have create a minimal reproducer (just using plain C) which presents the problem and show the crash:
When this is run, it will show that child crashes (segfault) due to accessing invalid memory which happens during
dispatch_activate
.Is this issue known and is libdispatch not usable after the fork? Potentially is there anything that can be done to get around this issue (except not doing fork)?
The text was updated successfully, but these errors were encountered: