Repository: elastic/apm-agent-php (php)

Issue:
Forked process runs indefinitely
**Describe the bug**
If I have the APM extension enabled and fork a child, the forked child **never stops**.

**To Reproduce**
```php
<?php

$child = $pid = pcntl_fork();
if ($child === 0)
{
	sleep(1);
	echo "\n\n-----------------------CHILD EXITING-------------------------\n\n";
	exit(0);
}

if ($child > 0)
{
	echo "\n\n-----------------------Forked child, waiting for it to end-------------------------\n\n";
	pcntl_wait($status);
	echo "\n\n-----------------------Child stopped-------------------------\n\n";
}

```

**Expected behavior**
The script should end after 1 second. Instead, it goes on indefinitely because the child process never stops.

**Logs**
With the log level set to trace, a normal process & forked process gives the same output:
```
-18 01:19:33.127062+00:00 [PID: 12903] [TID: 12903] [DEBUG]    [Ext-API] [elastic_apm_API.c:229] [elasticApmSendToServer] Exiting...; resultCode: resultSuccess (0); 
2022-02-18 01:19:33.127099+00:00 [PID: 12903] [TID: 12903] [DEBUG]    [Bootstrap] [BootstrapStageLogger.php:215] [shutdown] Successfully completed shutdown sequence
2022-02-18 01:19:33.127153+00:00 [PID: 12903] [TID: 12903] [DEBUG]    [Util] [util_for_PHP.c:154] [callPhpFunction] Exiting...; resultCode: resultSuccess (0); 
2022-02-18 01:19:33.127172+00:00 [PID: 12903] [TID: 12903] [DEBUG]    [C-to-PHP] [tracer_PHP_part.c:110] [shutdownTracerPhpPart] Exiting...; resultCode: resultSuccess (0); 
2022-02-18 01:19:33.127206+00:00 [PID: 12903] [TID: 12903] [DEBUG]    [Lifecycle] [lifecycle.c:351] [elasticApmRequestShutdown] Exiting...; resultCode: resultSuccess (0);
```

Pull request:
Fix forked process not exiting
Fixes #627

Patch:
diff --git a/Dockerfile b/Dockerfile
index b56e7b43..07566f95 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,7 +15,7 @@ RUN apt-get -qq update \
     --no-install-recommends \
  && rm -rf /var/lib/apt/lists/*
 
-COPY --from=composer:1.10.10 /usr/bin/composer /usr/bin/composer
+COPY --from=composer:2.3.5 /usr/bin/composer /usr/bin/composer
 
 RUN wget -q https://github.com/Kitware/CMake/releases/download/v3.20.5/cmake-3.20.5-Linux-x86_64.tar.gz -O /tmp/cmake.tar.gz \
       && mkdir /usr/bin/cmake \
diff --git a/Dockerfile.alpine b/Dockerfile.alpine
index d271fdb1..bac44e26 100644
--- a/Dockerfile.alpine
+++ b/Dockerfile.alpine
@@ -14,7 +14,7 @@ RUN apk update \
     procps \
     unzip
 
-COPY --from=composer:1.10.10 /usr/bin/composer /usr/bin/composer
+COPY --from=composer:2.3.5 /usr/bin/composer /usr/bin/composer
 
 WORKDIR /app/src/ext
 
diff --git a/src/ext/lifecycle.c b/src/ext/lifecycle.c
index de23e5a0..cafe654e 100644
--- a/src/ext/lifecycle.c
+++ b/src/ext/lifecycle.c
@@ -93,6 +93,22 @@ void logSupportabilityInfo( LogLevel logLevel )
     goto finally;
 }
 
+static pid_t g_pidOnRequestInit = -1;
+
+bool doesCurrentPidMatchPidOnRequestInit()
+{
+    pid_t currentPid = getCurrentProcessId();
+    if ( g_pidOnRequestInit != currentPid )
+    {
+        ELASTIC_APM_LOG_DEBUG( "Process ID on request init doesn't match the current process ID"
+                               " (maybe the current process is a child process forked after the request started?)"
+                               "; g_pidOnRequestInit: %d, currentPid: %d"
+                               , (int)g_pidOnRequestInit, (int)currentPid );
+        return false;
+    }
+    return true;
+}
+
 void elasticApmModuleInit( int type, int moduleNumber )
 {
     ELASTIC_APM_UNUSED( type );
@@ -165,6 +181,14 @@ void elasticApmModuleShutdown( int type, int moduleNumber )
 
     ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY();
 
+    if ( ! doesCurrentPidMatchPidOnRequestInit() )
+    {
+        resultCode = resultSuccess;
+        ELASTIC_APM_LOG_DEBUG_FUNCTION_EXIT();
+        ELASTIC_APM_UNUSED( resultCode );
+        return;
+    }
+
     Tracer* const tracer = getGlobalTracer();
     const ConfigSnapshot* const config = getTracerCurrentConfigSnapshot( tracer );
 
@@ -427,6 +451,8 @@ void elasticApmRequestInit()
     ZEND_TSRMLS_CACHE_UPDATE();
 #endif
 
+    g_pidOnRequestInit = getCurrentProcessId();
+
     TimePoint requestInitStartTime;
     getCurrentTime( &requestInitStartTime );
 
@@ -520,6 +546,12 @@ void elasticApmRequestShutdown()
 
     ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY();
 
+    if ( ! doesCurrentPidMatchPidOnRequestInit() )
+    {
+        resultCode = resultSuccess;
+        goto finally;
+    }
+
     if ( ! tracer->isInited )
     {
         ELASTIC_APM_LOG_TRACE( "Extension is not initialized" );


Test patch:
diff --git a/packaging/test/alpine/Dockerfile b/packaging/test/alpine/Dockerfile
index f88d4c7d..6319cc76 100644
--- a/packaging/test/alpine/Dockerfile
+++ b/packaging/test/alpine/Dockerfile
@@ -12,7 +12,7 @@ RUN apk update \
     unzip \
     wget
 
-COPY --from=composer:2.0.13 /usr/bin/composer /usr/bin/composer
+COPY --from=composer:2.3.5 /usr/bin/composer /usr/bin/composer
 
 RUN php -v
 
diff --git a/packaging/test/centos/Dockerfile b/packaging/test/centos/Dockerfile
index 16e98b99..ad993874 100644
--- a/packaging/test/centos/Dockerfile
+++ b/packaging/test/centos/Dockerfile
@@ -15,7 +15,7 @@ RUN yum update -y \
     && yum install -y git gnupg2 perl-Digest-SHA unzip wget \
     && yum clean all
 
-COPY --from=composer:2.0.13 /usr/bin/composer /usr/bin/composer
+COPY --from=composer:2.3.5 /usr/bin/composer /usr/bin/composer
 
 # To support tar and rpm packages
 ENV TYPE=rpm
diff --git a/packaging/test/ubuntu/Dockerfile b/packaging/test/ubuntu/Dockerfile
index 6a2b4382..71da71f5 100644
--- a/packaging/test/ubuntu/Dockerfile
+++ b/packaging/test/ubuntu/Dockerfile
@@ -1,7 +1,7 @@
 ARG PHP_VERSION=7.2
 FROM php:${PHP_VERSION}-fpm
 
-COPY --from=composer:2.0.13 /usr/bin/composer /usr/bin/composer
+COPY --from=composer:2.3.5 /usr/bin/composer /usr/bin/composer
 
 # sh: 1: ps: not found
 # sh: 1: git: not found
diff --git a/packaging/test/ubuntu/apache/Dockerfile b/packaging/test/ubuntu/apache/Dockerfile
index 73e06532..9a7b3002 100644
--- a/packaging/test/ubuntu/apache/Dockerfile
+++ b/packaging/test/ubuntu/apache/Dockerfile
@@ -4,7 +4,7 @@ ENV DEBIAN_FRONTEND=noninteractive
 RUN apt-get -qq update \
     && apt-get -qq install -y dpkg-sig gnupg gnupg2 git procps zlib1g-dev libzip-dev wget unzip rsyslog --no-install-recommends
 
-COPY --from=composer:1.10.10 /usr/bin/composer /usr/bin/composer
+COPY --from=composer:2.3.5 /usr/bin/composer /usr/bin/composer
 
 COPY entrypoint.sh /bin
 
diff --git a/packaging/test/ubuntu/fpm/Dockerfile b/packaging/test/ubuntu/fpm/Dockerfile
index 6e7446e8..3c8b3291 100644
--- a/packaging/test/ubuntu/fpm/Dockerfile
+++ b/packaging/test/ubuntu/fpm/Dockerfile
@@ -4,7 +4,7 @@ ENV DEBIAN_FRONTEND=noninteractive
 RUN apt-get -qq update \
     && apt-get -qq install -y dpkg-sig gnupg gnupg2 git procps zlib1g-dev libzip-dev wget unzip rsyslog --no-install-recommends
 
-COPY --from=composer:1.10.10 /usr/bin/composer /usr/bin/composer
+COPY --from=composer:2.3.5 /usr/bin/composer /usr/bin/composer
 
 COPY entrypoint.sh /bin