Problema
Su sitio genera errores de segmentación cuando el agente PHP de New Relic (versiones 10.18.0.8 o superiores) está habilitado en PHP 8.0+.
Descripción
La API Observer de PHP actualmente tiene algunos errores que pueden provocar fallas de segmentación. El agente PHP New Relic emplea OAPI para instrumentar su aplicación en PHP 8.0+ desde la versión 10.18 del agente. Estas fallas de segmentación solo ocurren cuando el agente está habilitado. Esto se debe a que las rutas de código OAPI de PHP solo se ejecutan si hay un observador conectado y, con toda probabilidad, el agente PHP de New Relic es lo único en su entorno que se conecta a OAPI.
Traza
En estas situaciones, el rastreo de la stack parece ser relativamente consistente. Lo que vemos es, como siempre, el controlador de señal fatal nr
en la parte superior. Todo lo que hay en la stack por encima de nr_php_fatal_signal_handler
siempre estará presente ante una falla de segmentación cuando se instala el agente PHP, ya que detectamos la falla con fines de logging. Luego, vemos que el controlador de señales fue llamado durante zend_observer_fcall_end_all
. Esto sucede cuando PHP accede a una memoria no válida al intentar llamar a todos los observadores registrados. Cada vez que vemos zend_observer_*
en el rastreo del stack sin ningún código New Relic antes del controlador de señales, deberían surgir algunas preguntas sobre si PHP es el problema.
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
Puedes probar si el problema es PHP o el agente. PHP tiene una extensión incorporada llamada zend_test
que tiene un observador de pruebas. Al habilitar esto (mientras se deshabilita el agente), se permite que las rutas de código OAPI sean ejecutadas por algo que no sea nuestro agente. Estos son los pasos para probarlo:
- Deshabilite completamente el agente configurando
newrelic.enabled=0
. Pruebe aquí para cerciorar de que esté realmente deshabilitado. - Habilitar la extensión PHP
zend_test
. Esto se puede hacer modificando su Dockerfile como se muestra a continuación. - Establezca los ajustes
ini
zend_test.observer.enabled=1
yzend_test.observer.observe_all=1
. Esto debería habilitar la API de observador de PHP. - Vea si el problema se puede reproducir en estas circunstancias.
A continuación se muestra un ejemplo para Debian que emplea una imagen 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
A continuación se muestra un ejemplo que emplea una imagen docker PHP de 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
A continuación se muestra un ejemplo de la salida phpinfo()
si la extensión está instalada y habilitada como se indica anteriormente:
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
Reproducción conocida y seguimiento de la solución
Consulte esta página php-src que muestra problemas relacionados con OAPI y fallas de segmentación.
Recomendamos actualizar a la versión más reciente de PHP para recibir las correcciones pertinentes a medida que se publiquen.