diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a5771852..84b79d693 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,7 +81,7 @@ jobs: - name: Remove OpenTelemetry dependencies on unsupported PHP versions if: ${{ matrix.php.version == '7.2' || matrix.php.version == '7.3' || matrix.php.version == '7.4' || matrix.php.version == '8.0' }} - run: composer remove open-telemetry/api open-telemetry/exporter-otlp open-telemetry/sdk --dev --no-interaction --no-update + run: composer remove open-telemetry/api open-telemetry/exporter-otlp open-telemetry/sem-conv open-telemetry/sdk --dev --no-interaction --no-update - name: Set phpunit/phpunit version constraint run: composer require phpunit/phpunit:'${{ matrix.php.phpunit }}' --dev --no-interaction --no-update diff --git a/composer.json b/composer.json index a7554ac77..d231477c6 100644 --- a/composer.json +++ b/composer.json @@ -39,6 +39,7 @@ "nyholm/psr7": "^1.8", "open-telemetry/api": "^1.0", "open-telemetry/exporter-otlp": "^1.0", + "open-telemetry/sem-conv": "^1.27", "open-telemetry/sdk": "^1.0", "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^8.5.52|^9.6.34", diff --git a/src/ErrorHandler.php b/src/ErrorHandler.php index 3f3dd2d83..ec9ed6ade 100644 --- a/src/ErrorHandler.php +++ b/src/ErrorHandler.php @@ -117,6 +117,11 @@ final class ErrorHandler */ private static $reservedMemory; + /** + * @var int The amount of memory to reserve for the fatal error handler + */ + private static $reservedMemorySize = self::DEFAULT_RESERVED_MEMORY_SIZE; + /** * @var bool Whether the fatal error handler should be disabled */ @@ -214,6 +219,7 @@ public static function registerOnceFatalErrorHandler(int $reservedMemorySize = s } self::$handlerInstance->isFatalErrorHandlerRegistered = true; + self::$reservedMemorySize = $reservedMemorySize; self::$reservedMemory = str_repeat('x', $reservedMemorySize); register_shutdown_function(\Closure::fromCallable([self::$handlerInstance, 'handleFatalError'])); @@ -301,6 +307,19 @@ public function setMemoryLimitIncreaseOnOutOfMemoryErrorInBytes(?int $valueInByt $this->memoryLimitIncreaseOnOutOfMemoryErrorValue = $valueInBytes; } + /** + * @internal + */ + public static function resetFatalErrorHandlerState(): void + { + self::$disableFatalErrorHandler = false; + self::$didIncreaseMemoryLimit = false; + + if (self::$handlerInstance !== null && self::$handlerInstance->isFatalErrorHandlerRegistered) { + self::$reservedMemory = str_repeat('x', self::$reservedMemorySize); + } + } + /** * Handles errors by capturing them through the client according to the * configured bit field. diff --git a/src/State/RuntimeContextManager.php b/src/State/RuntimeContextManager.php index 43b46fb65..1c218b80a 100644 --- a/src/State/RuntimeContextManager.php +++ b/src/State/RuntimeContextManager.php @@ -6,6 +6,7 @@ use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; +use Sentry\ErrorHandler; use Sentry\Tracing\PropagationContext; /** @@ -113,6 +114,8 @@ public function startContext(): void return; } + ErrorHandler::resetFatalErrorHandlerState(); + $this->createContextForExecutionContextKey($executionContextKey); } diff --git a/tests/Fixtures/OpenTelemetry/TestDiscoveryStrategy.php b/tests/Fixtures/OpenTelemetry/TestDiscoveryStrategy.php index 6477cf190..2144bd1f7 100644 --- a/tests/Fixtures/OpenTelemetry/TestDiscoveryStrategy.php +++ b/tests/Fixtures/OpenTelemetry/TestDiscoveryStrategy.php @@ -4,6 +4,7 @@ namespace Sentry\Tests\Fixtures\OpenTelemetry; +use GuzzleHttp\Psr7\HttpFactory; use Nyholm\Psr7\Factory\Psr17Factory; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; @@ -21,7 +22,10 @@ public static function getCandidates(string $type): array } if (is_a(RequestFactoryInterface::class, $type, true) || is_a(StreamFactoryInterface::class, $type, true)) { - return [['class' => Psr17Factory::class, 'condition' => Psr17Factory::class]]; + return [ + ['class' => HttpFactory::class, 'condition' => HttpFactory::class], + ['class' => Psr17Factory::class, 'condition' => Psr17Factory::class], + ]; } return []; diff --git a/tests/Integration/OTLPIntegrationTest.php b/tests/Integration/OTLPIntegrationTest.php index a0f3e5680..27f4807b8 100644 --- a/tests/Integration/OTLPIntegrationTest.php +++ b/tests/Integration/OTLPIntegrationTest.php @@ -280,10 +280,10 @@ private function useCapturingHttpClient(): void if (method_exists(HttpClientDiscovery::class, 'setDiscoverers')) { HttpClientDiscovery::setDiscoverers([new TestClientDiscoverer()]); - } else { - ClassDiscovery::prependStrategy(TestDiscoveryStrategy::class); } + ClassDiscovery::prependStrategy(TestDiscoveryStrategy::class); + StubOtelHttpClient::reset(); } diff --git a/tests/phpt/error_handler_reset_fatal_error_handler_state.phpt b/tests/phpt/error_handler_reset_fatal_error_handler_state.phpt new file mode 100644 index 000000000..eb23dfac5 --- /dev/null +++ b/tests/phpt/error_handler_reset_fatal_error_handler_state.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test that resetting the fatal error handler state re-arms OOM handling +--FILE-- +setAccessible(true); + + return $property; +} + +function setErrorHandlerStaticProperty(string $name, $value): void +{ + getErrorHandlerProperty($name)->setValue(null, $value); +} + +function getErrorHandlerStaticProperty(string $name) +{ + return getErrorHandlerProperty($name)->getValue(); +} + +ErrorHandler::registerOnceFatalErrorHandler(1234); + +setErrorHandlerStaticProperty('disableFatalErrorHandler', true); +setErrorHandlerStaticProperty('didIncreaseMemoryLimit', true); +setErrorHandlerStaticProperty('reservedMemory', null); + +ErrorHandler::resetFatalErrorHandlerState(); + +var_dump(getErrorHandlerStaticProperty('disableFatalErrorHandler')); +var_dump(getErrorHandlerStaticProperty('didIncreaseMemoryLimit')); +var_dump(\strlen(getErrorHandlerStaticProperty('reservedMemory'))); + +?> +--EXPECT-- +bool(false) +bool(false) +int(1234)