Skip to content

SIGSEGV during PHP shutdown after persistent connection cleanup (v11.0.1) #295

Description

@satwareAG-ironMike

Description

After running a full PHPUnit test suite (642 functional tests) with php-firebird v11.0.1, PHP crashes with SIGSEGV (exit code 139) during shutdown. The crash occurs AFTER all tests have passed and PHPUnit has reported results. The crash is in the persistent connection cleanup path during MSHUTDOWN.

Reproduction

Environment:

  • php-firebird v11.0.1
  • PHP 8.4.22
  • Firebird 3.0.14 (firebirdsql/firebird:3 Docker image)
  • Exception Mode enabled (FBIRD_EXCEPTION_MODE_THROW)

Run a test suite that creates and closes multiple Firebird\Connection objects:

docker compose run --rm app bash -c "cd tests && ../vendor/bin/phpunit --configuration phpunit.xml --no-coverage --testsuite Functional 2>&1"

Expected output

OK, but there were issues!
Tests: 642, Assertions: 1607, Skipped: 117, Incomplete: 2.
# clean exit

Actual output

OK, but there were issues!
Tests: 642, Assertions: 1607, Skipped: 117, Incomplete: 2.
bash: line 1:     8 Segmentation fault      (core dumped) ../vendor/bin/phpunit ...

Exit code: 139 (128 + 11 = SIGSEGV)

Impact

The crash occurs after tests complete, so test results are not affected. However:

  1. CI pipelines may report the job as failed (non-zero exit code)
  2. Coverage reports may not be written if the crash interrupts file I/O
  3. The doctrine-firebird-driver CI has a workaround that checks for exit code 139 and treats it as success if PHPUnit reported OK

Analysis

The crash likely occurs in _php_fbird_close_plink() during MSHUTDOWN, similar to the v10.x issue fixed in commit 881d375 (MSHUTDOWN pconnect SIGSEGV). The M3 opaque-object migration may have introduced a new code path where the Firebird\Connection object's internal resource is freed during MSHUTDOWN while the object is still referenced.

The crash does NOT occur with non-persistent connections (the driver uses persistent = false for tests). It may be related to the extension's internal cleanup of the default link or the le_plink resource list.

Workaround

The doctrine-firebird-driver CI handles this by checking exit code 139:

if [ $EXIT_CODE -eq 139 ]; then
    if echo "$OUTPUT" | grep -qE '^OK' && [ -f ../coverage.xml ]; then
        echo "⚠️  WARNING: PHP process crashed with SIGSEGV (exit 139) during shutdown"
        echo "   PHPUnit reported success - treating as success."
    fi
fi

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions