Problème
Votre site génère des erreurs de segmentation lorsque l'agent PHP New Relic (versions 10.18.0.8 ou supérieures) est activé sur PHP 8.0+.
Description
L'API Observer de PHP présente actuellement quelques bugs qui peuvent entraîner des erreurs de segmentation. L'agent PHP New Relic utilise OAPI pour instrumenter votre application sur PHP 8.0+ depuis la agent version 10.18. Ces erreurs de segmentation se produisent uniquement lorsque l'agent est activé. Cela est dû au fait que les chemins de code OAPI de PHP ne sont exécutés que s'il y a un observateur connecté et, selon toute vraisemblance, l'agent PHP New Relic est la seule chose dans votre environnement qui se connecte à OAPI.
tracer
Dans ces situations, la trace d'appels semble être relativement cohérente. Ce que nous voyons est, comme toujours, le gestionnaire de signal fatal nr
en haut. Tout ce qui se trouve dans la stack au-dessus de nr_php_fatal_signal_handler
sera toujours présent en cas d'erreur de segmentation lorsque l' agent PHP est installé, car nous capturons l'erreur à des fins de logging. Ensuite, nous voyons que le gestionnaire de signal a été appelé pendant zend_observer_fcall_end_all
. Cela se produit lorsque PHP accède à une mémoire non valide lors de la tentative d'appel de tous les observateurs enregistrés. Chaque fois que nous voyons zend_observer_*
dans la trace d'appels sans aucun code New Relic avant le gestionnaire de signal, cela devrait soulever des questions quant à savoir si PHP est le problème.
0 nr_php_backtrace_get_call_site () at php_stack.c:220
1 nr_php_frame_info () at php_stack.c:267
2 nr_php_backtrace_fd () at php_stack.c:462
3 0x00007fa6d6df026c in nr_php_fatal_signal_handler () at php_minit.c:740
<signal handler called>
5 0x00007fa6db184c63 in zend_observer_fcall_end_all () from libphp8.2.so
6 0x00007fa6db081abd in php_request_shutdown () from libphp8.2.so
zend_test
Vous pouvez tester si le problème vient de PHP ou de l'agent. PHP possède une extension intégrée appelée zend_test
qui possède un observateur de test. L'activation de cette option (tout en désactivant l'agent) permet aux chemins de code OAPI d'être exécutés par autre chose que notre agent. Voici les étapes pour tester ceci :
- Désactivez complètement l'agent en définissant
newrelic.enabled=0
. Testez ici pour vous assurer qu'il est bien désactivé. - Activer l'extension PHP
zend_test
. Cela peut être fait en modifiant votre Dockerfile comme indiqué ci-dessous. - Définissez les paramètres
ini
zend_test.observer.enabled=1
etzend_test.observer.observe_all=1
. Cela devrait activer l'API d'observation de PHP. - Voyez si le problème peut être reproduit dans ces circonstances.
Voici un exemple pour Debian utilisant une image docker PHP :
FROM php:8.0
RUN apt update && apt install -y libxml2-dev && \ EXTRA_CFLAGS="$(xml2-config --cflags) -I/usr/src/php" docker-php-ext-install zend_test
RUN echo "zend_test.observer.enabled=1" >> $(php-config --ini-dir)/docker-php-ext-zend_test.iniRUN echo "zend_test.observer.observe_all=1" >> $(php-config --ini-dir)/docker-php-ext-zend_test.ini
Voici un exemple utilisant une image Docker PHP Alpine :
FROM php:8.0-alpine
RUN apk add --no-cache libxml2-dev && \ EXTRA_CFLAGS="$(xml2-config --cflags) -I/usr/src/php" docker-php-ext-install zend_test
RUN echo "zend_test.observer.enabled=1" >> $(php-config --ini-dir)/docker-php-ext-zend_test.iniRUN echo "zend_test.observer.observe_all=1" >> $(php-config --ini-dir)/docker-php-ext-zend_test.ini
Voici un exemple de sortie phpinfo()
si l'extension est installée et activée comme indiqué ci-dessus :
zend_test
zend_test extension => enabled
Directive => Local Value => Master Valuezend_test.limit_copy_file_range => -1 => -1zend_test.not_empty_str_test => val => valzend_test.observe_opline_in_zendmm => Off => Offzend_test.observer.enabled => On => Onzend_test.observer.execute_internal => Off => Offzend_test.observer.fiber_destroy => Off => Offzend_test.observer.fiber_init => Off => Offzend_test.observer.fiber_switch => Off => Offzend_test.observer.observe_all => On => Onzend_test.observer.observe_declaring => Off => Offzend_test.observer.observe_function_names => no value => no valuezend_test.observer.observe_functions => Off => Offzend_test.observer.observe_includes => Off => Offzend_test.observer.show_init_backtrace => Off => Offzend_test.observer.show_opcode => Off => Offzend_test.observer.show_opcode_in_user_handler => no value => no valuezend_test.observer.show_output => On => Onzend_test.observer.show_return_type => Off => Offzend_test.observer.show_return_value => Off => Offzend_test.print_stderr_mshutdown => Off => Offzend_test.quantity_value => 0 => 0zend_test.register_passes => Off => Offzend_test.replace_zend_execute_ex => Off => Offzend_test.str_test => no value => no value
Reproduction connue et suivi du correctif
Consultez cette page php-src qui présente les problèmes liés à l'OAPI et aux défauts de segmentation.
Nous vous recommandons de mettre à jour vers la version PHP la plus récente pour recevoir les correctifs pertinents dès leur sortie.