From cbf457d5b72e7352cd1af9d147e3659ee7f10732 Mon Sep 17 00:00:00 2001 From: Norbert Orzechowicz Date: Fri, 12 Jun 2026 10:55:51 +0200 Subject: [PATCH 1/2] fix: set experimental env var on grpc to avoid crashes --- .github/workflows/job-tests.yml | 39 ++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/.github/workflows/job-tests.yml b/.github/workflows/job-tests.yml index b83192fd7..7dae70b2a 100644 --- a/.github/workflows/job-tests.yml +++ b/.github/workflows/job-tests.yml @@ -48,8 +48,7 @@ jobs: matrix: dependencies: ${{ fromJSON(inputs.dependencies) }} php-version: - - "8.3" - - "8.4" + # DEBUG BRANCH: only 8.5 (the crashing job). Revert before merge. - "8.5" operating-system: - "ubuntu-latest" @@ -93,7 +92,8 @@ jobs: with: php-version: "${{ matrix.php-version }}" dependencies: "${{ matrix.dependencies }}" - coverage: ${{ matrix.php-version == '8.3' && 'pcov' || 'none' }} + coverage: 'pcov' # DEBUG BRANCH: force pcov on 8.5 to match the crashing config. Revert before merge. + # DEBUG: grpc restored; testing GRPC_EXPERIMENTS=-work_serializer_dispatch workaround (grpc#38216) for the shutdown SIGSEGV. Revert before merge. extensions: ':psr, bcmath, dom, hash, json, mbstring, xml, xmlwriter, xmlreader, zlib, curl, pgsql, grpc, protobuf' ini-values: 'memory_limit=-1, post_max_size=32M, upload_max_filesize=32M' apt-packages: "build-essential autoconf automake libtool protobuf-compiler libprotobuf-c-dev" @@ -123,9 +123,34 @@ jobs: env: AZURITE_ACCOUNTS: flowphpaccount01:flowphpkey01 - - name: "Test" - timeout-minutes: 10 - run: "just test --log-junit ./var/phpunit/logs/junit.xml ${{ matrix.php-version == '8.3' && '--coverage-clover=./var/phpunit/coverage/clover/coverage.xml' || '' }}" + # DEBUG BRANCH: run phpunit under gdb so the PHP 8.5 shutdown SIGSEGV prints a + # backtrace + loaded shared libraries (identifies the crashing extension even + # without debug symbols). `handle all nostop ... pass` then re-enabling stop for + # SIGSEGV/SIGABRT avoids gdb halting on glibc's threading signals (SIG32/33). + # Whole step is temporary — revert this file before merging. + - name: "Test (DEBUG: gdb backtrace on segfault)" + timeout-minutes: 25 + run: | + sudo apt-get update -qq && sudo apt-get install -y -qq gdb + ulimit -c unlimited + mkdir -p ./var/phpunit/coverage/clover ./var/phpunit/logs + gdb -batch -nx \ + -ex "set pagination off" \ + -ex "set confirm off" \ + -ex "handle all nostop noprint pass" \ + -ex "handle SIGSEGV stop print pass" \ + -ex "handle SIGABRT stop print pass" \ + -ex "run" \ + -ex "printf \"\n===== CRASHING THREAD BACKTRACE =====\n\"" \ + -ex "bt full" \ + -ex "printf \"\n===== ALL THREAD BACKTRACES =====\n\"" \ + -ex "thread apply all bt" \ + -ex "printf \"\n===== LOADED SHARED LIBRARIES =====\n\"" \ + -ex "info sharedlibrary" \ + --args "$(which php)" -d pcov.enabled=1 -d memory_limit=-1 \ + tools/phpunit/vendor/bin/phpunit \ + --coverage-clover=./var/phpunit/coverage/clover/coverage.xml \ + --log-junit ./var/phpunit/logs/junit.xml env: PGSQL_DATABASE_URL: pgsql://postgres:postgres@127.0.0.1:${{ job.services.postgres.ports['5432'] }}/postgres?serverVersion=11&charset=utf8 MYSQL_DATABASE_URL: mysql://mysql:mysql@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/mysql @@ -142,6 +167,8 @@ jobs: OTEL_RECEIVER_GRPC_ENDPOINT: "localhost:4317" OTEL_COLLECTOR_METRICS_ENDPOINT: "http://localhost:8888/metrics" FLOW_PARQUET_TESTS_DEBUG: "0" + # DEBUG: grpc#38216 maintainer-suggested workaround for the event_engine/dlclose shutdown SIGSEGV. Revert before merge. + GRPC_EXPERIMENTS: "-work_serializer_dispatch" - name: Upload to Codecov uses: ./.github/actions/codecov-report From d1a559c290998da3815a7a75c14f3a5f8519093c Mon Sep 17 00:00:00 2001 From: Norbert Orzechowicz Date: Fri, 12 Jun 2026 11:43:04 +0200 Subject: [PATCH 2/2] fix(flow-php/telemetry-otlp-bridge): isolate grpc tests from PHP 8.5 shutdown segfault - tag grpc-exercising tests with #[Group('grpc')] - split CI into main (--exclude-group grpc) and grpc steps - grpc step continue-on-error on 8.5 only (upstream grpc#38216) --- .github/workflows/job-tests.yml | 66 +++++++++---------- .../Integration/LogExportIntegrationTest.php | 2 + .../MetricExportIntegrationTest.php | 2 + .../Integration/SpanExportIntegrationTest.php | 2 + .../Unit/Transport/GrpcTransportTest.php | 2 + 5 files changed, 41 insertions(+), 33 deletions(-) diff --git a/.github/workflows/job-tests.yml b/.github/workflows/job-tests.yml index 7dae70b2a..b9421e948 100644 --- a/.github/workflows/job-tests.yml +++ b/.github/workflows/job-tests.yml @@ -48,7 +48,8 @@ jobs: matrix: dependencies: ${{ fromJSON(inputs.dependencies) }} php-version: - # DEBUG BRANCH: only 8.5 (the crashing job). Revert before merge. + - "8.3" + - "8.4" - "8.5" operating-system: - "ubuntu-latest" @@ -92,8 +93,7 @@ jobs: with: php-version: "${{ matrix.php-version }}" dependencies: "${{ matrix.dependencies }}" - coverage: 'pcov' # DEBUG BRANCH: force pcov on 8.5 to match the crashing config. Revert before merge. - # DEBUG: grpc restored; testing GRPC_EXPERIMENTS=-work_serializer_dispatch workaround (grpc#38216) for the shutdown SIGSEGV. Revert before merge. + coverage: ${{ matrix.php-version == '8.3' && 'pcov' || 'none' }} extensions: ':psr, bcmath, dom, hash, json, mbstring, xml, xmlwriter, xmlreader, zlib, curl, pgsql, grpc, protobuf' ini-values: 'memory_limit=-1, post_max_size=32M, upload_max_filesize=32M' apt-packages: "build-essential autoconf automake libtool protobuf-compiler libprotobuf-c-dev" @@ -123,34 +123,36 @@ jobs: env: AZURITE_ACCOUNTS: flowphpaccount01:flowphpkey01 - # DEBUG BRANCH: run phpunit under gdb so the PHP 8.5 shutdown SIGSEGV prints a - # backtrace + loaded shared libraries (identifies the crashing extension even - # without debug symbols). `handle all nostop ... pass` then re-enabling stop for - # SIGSEGV/SIGABRT avoids gdb halting on glibc's threading signals (SIG32/33). - # Whole step is temporary — revert this file before merging. - - name: "Test (DEBUG: gdb backtrace on segfault)" - timeout-minutes: 25 - run: | - sudo apt-get update -qq && sudo apt-get install -y -qq gdb - ulimit -c unlimited - mkdir -p ./var/phpunit/coverage/clover ./var/phpunit/logs - gdb -batch -nx \ - -ex "set pagination off" \ - -ex "set confirm off" \ - -ex "handle all nostop noprint pass" \ - -ex "handle SIGSEGV stop print pass" \ - -ex "handle SIGABRT stop print pass" \ - -ex "run" \ - -ex "printf \"\n===== CRASHING THREAD BACKTRACE =====\n\"" \ - -ex "bt full" \ - -ex "printf \"\n===== ALL THREAD BACKTRACES =====\n\"" \ - -ex "thread apply all bt" \ - -ex "printf \"\n===== LOADED SHARED LIBRARIES =====\n\"" \ - -ex "info sharedlibrary" \ - --args "$(which php)" -d pcov.enabled=1 -d memory_limit=-1 \ - tools/phpunit/vendor/bin/phpunit \ - --coverage-clover=./var/phpunit/coverage/clover/coverage.xml \ - --log-junit ./var/phpunit/logs/junit.xml + # Main suite: everything except the grpc-exercising tests, so grpc is never + # exercised here and the process shuts down cleanly. Must pass. + - name: "Test" + timeout-minutes: 15 + run: "just test --exclude-group grpc --log-junit ./var/phpunit/logs/junit.xml ${{ matrix.php-version == '8.3' && '--coverage-clover=./var/phpunit/coverage/clover/coverage.xml' || '' }}" + env: + PGSQL_DATABASE_URL: pgsql://postgres:postgres@127.0.0.1:${{ job.services.postgres.ports['5432'] }}/postgres?serverVersion=11&charset=utf8 + MYSQL_DATABASE_URL: mysql://mysql:mysql@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/mysql + SQLITE_DATABASE_URL: "sqlite:///:memory:" + AZURITE_HOST: "localhost" + AZURITE_BLOB_PORT: "10000" + AZURITE_ACCOUNT_NAME: "flowphpaccount01" + AZURITE_ACCOUNT_KEY: "flowphpkey01" + S3_ENDPOINT: "http://localhost:9000" + S3_REGION: "us-east-1" + S3_ACCESS_KEY_ID: "minioadmin" + S3_SECRET_ACCESS_KEY: "minioadmin" + OTEL_RECEIVER_HTTP_ENDPOINT: "http://localhost:4318" + OTEL_RECEIVER_GRPC_ENDPOINT: "localhost:4317" + OTEL_COLLECTOR_METRICS_ENDPOINT: "http://localhost:8888/metrics" + FLOW_PARQUET_TESTS_DEBUG: "0" + + # gRPC-exercising tests, isolated. grpc's EventEngine threads race PHP's extension + # dlclose at process shutdown on PHP 8.5/amd64 (upstream grpc#38216, no released fix), + # so this step is allowed to fail ONLY on 8.5. A real grpc test regression on 8.3/8.4 + # still fails CI. Remove continue-on-error once grpc ships a fix. + - name: "Test (grpc)" + timeout-minutes: 10 + continue-on-error: ${{ matrix.php-version == '8.5' }} + run: "just test --group grpc --log-junit ./var/phpunit/logs/grpc-junit.xml" env: PGSQL_DATABASE_URL: pgsql://postgres:postgres@127.0.0.1:${{ job.services.postgres.ports['5432'] }}/postgres?serverVersion=11&charset=utf8 MYSQL_DATABASE_URL: mysql://mysql:mysql@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/mysql @@ -167,8 +169,6 @@ jobs: OTEL_RECEIVER_GRPC_ENDPOINT: "localhost:4317" OTEL_COLLECTOR_METRICS_ENDPOINT: "http://localhost:8888/metrics" FLOW_PARQUET_TESTS_DEBUG: "0" - # DEBUG: grpc#38216 maintainer-suggested workaround for the event_engine/dlclose shutdown SIGSEGV. Revert before merge. - GRPC_EXPERIMENTS: "-work_serializer_dispatch" - name: Upload to Codecov uses: ./.github/actions/codecov-report diff --git a/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/LogExportIntegrationTest.php b/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/LogExportIntegrationTest.php index d23aff484..d4094b41e 100644 --- a/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/LogExportIntegrationTest.php +++ b/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/LogExportIntegrationTest.php @@ -7,7 +7,9 @@ use Flow\Bridge\Telemetry\OTLP\Tests\Context\TransportConfiguration; use Flow\Telemetry\Resource; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +#[Group('grpc')] final class LogExportIntegrationTest extends IntegrationTestCase { #[DataProvider('transportProvider')] diff --git a/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/MetricExportIntegrationTest.php b/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/MetricExportIntegrationTest.php index 3cf6ef12e..81a30ef0e 100644 --- a/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/MetricExportIntegrationTest.php +++ b/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/MetricExportIntegrationTest.php @@ -7,7 +7,9 @@ use Flow\Bridge\Telemetry\OTLP\Tests\Context\TransportConfiguration; use Flow\Telemetry\Resource; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +#[Group('grpc')] final class MetricExportIntegrationTest extends IntegrationTestCase { #[DataProvider('transportProvider')] diff --git a/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/SpanExportIntegrationTest.php b/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/SpanExportIntegrationTest.php index 536a9ab1a..5b1b90f46 100644 --- a/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/SpanExportIntegrationTest.php +++ b/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Integration/SpanExportIntegrationTest.php @@ -15,7 +15,9 @@ use Flow\Telemetry\Tracer\SpanLink; use Flow\Telemetry\Tracer\SpanStatus; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +#[Group('grpc')] final class SpanExportIntegrationTest extends IntegrationTestCase { #[DataProvider('transportProvider')] diff --git a/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Unit/Transport/GrpcTransportTest.php b/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Unit/Transport/GrpcTransportTest.php index 7fada3045..f8edaff94 100644 --- a/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Unit/Transport/GrpcTransportTest.php +++ b/src/bridge/telemetry/otlp/tests/Flow/Bridge/Telemetry/OTLP/Tests/Unit/Transport/GrpcTransportTest.php @@ -13,6 +13,7 @@ use Google\Protobuf\Internal\Message; use Grpc\BaseStub; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\RequiresPhpExtension; use PHPUnit\Framework\TestCase; use RuntimeException; @@ -23,6 +24,7 @@ use function extension_loaded; use function str_contains; +#[Group('grpc')] final class GrpcTransportTest extends TestCase { #[RequiresPhpExtension('grpc')]