-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Description
Problem
PHP with gRPC enabled is unable to execute other binaries using simple exec() or popen() calls.
In error log I can see the following errors:
[14-Jul-2020 19:30:40] WARNING: [pool www] child 6 said into stderr: "php-fpm: pool www: /tmp/pear/temp/grpc/src/core/lib/gprpp/ref_counted.h:137: void grpc_core::RefCount::RefNonZero(const grpc_core::DebugLocation&, const char*): Assertion `prior > 0' failed."
[14-Jul-2020 19:30:42] WARNING: [pool www] child 7 said into stderr: "php-fpm: pool www: /tmp/pear/temp/grpc/src/core/lib/gprpp/ref_counted.h:137: void grpc_core::RefCount::RefNonZero(const grpc_core::DebugLocation&, const char*): Assertion `prior > 0' failed."
The first exec() call succeeds, but after that all exec() calls return empty result and I get an error message in the error log for each request to the script.
That happens even though both grpc.enable_fork_support and grpc.poll_strategy are used in php.ini
Versions
I'm using latest PHP gRPC version: 1.30.0 and tried several PHP versions: 7.4.5, latest 7.4-git, 7.2.
For some obscure reason I'm unable to reproduce the issue in my test environment, while I can easily reproduce it in production env (PHP 7.4.5) and using official docker containers (running PHP 7.2).
OS: OpenSuse, SLES, whatever Ubuntu version is used in official containers
gcc version 7.5.0
Steps to reproduce
- Run example node-server:
docker run -d -p 9090:9090 --name node-server grpcweb/node-server - Add exec() call to the client.php:
diff --git a/examples/php/echo/client.php b/examples/php/echo/client.php
index b482992871..8228f7dba2 100644
--- a/examples/php/echo/client.php
+++ b/examples/php/echo/client.php
@@ -19,6 +19,11 @@
require dirname(__FILE__).'/vendor/autoload.php';
+$ret = 0;
+$out = [];
+exec("uname", $out, $ret);
+var_dump($out, $ret);
+
$client = new Grpc\Gateway\Testing\EchoServiceClient('node-server:9090', [
'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
- Don't forget to enable fork support, otherwise gRPC will hang the PHP process indefinitely:
diff --git a/examples/php/echo/fpm.Dockerfile b/examples/php/echo/fpm.Dockerfile
index 6e2df8b013..582e6d25c5 100644
--- a/examples/php/echo/fpm.Dockerfile
+++ b/examples/php/echo/fpm.Dockerfile
@@ -37,6 +37,10 @@ COPY --from=grpc-base \
RUN docker-php-ext-enable grpc
+RUN echo '\
+grpc.enable_fork_support=1\n\
+grpc.poll_strategy=epoll1\n\
+' >> /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini
WORKDIR /var/www/html
-
Build FPM container:
docker build -t grpc-php/fpm -f ./fpm.Dockerfile .
and run it:
docker run -it --rm --link node-server:node-server -p 9000:9000 --name fpm grpc-php/fpm -
Run Nginx container
docker run -it --rm -v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf:ro --link fpm:fpm -p 80:80 nginx:1.17.4
Any request to http://localhost/index.php results in the mentioned error.
The same code (as in "gRPC loaded + exec()", since we're not using a demo node-server apparently) results in SIGABRT and a core dump in my production environment, which is quite a problem.
I'm still trying to reproduce the issue using my test environment, though.
Of course, I'm ready to provide any kind of additional info.