Problema
Seu site gera falhas de segmentação quando o agente PHP do New Relic (versões 10.18.0.8 ou superior) está habilitado no PHP 8.0+.
Descrição
A API Observer do PHP atualmente tem alguns bugs que podem levar a falhas de segmentação. O agente PHP New Relic utiliza OAPI para instrumentar seu aplicativo em PHPs 8.0+ desde a versão 10.18 do agente. Essas falhas de segmentação só acontecem quando o agente está habilitado. Isso ocorre porque os caminhos de código OAPI do PHP só são executados se houver um observador conectado e, com toda a probabilidade, o agente PHP do New Relic é a única coisa no seu ambiente conectada ao OAPI.
Trace
Nessas situações, o stack trace parece ser relativamente consistente. O que vemos é, como sempre, o manipulador de sinal fatal nr
no topo. Tudo na stack acima de nr_php_fatal_signal_handler
sempre estará presente para uma falha de segmentação quando o agente PHP for instalado, pois capturamos a falha para fins de logging. Então, vemos que o manipulador de sinal foi chamado durante zend_observer_fcall_end_all
. Isso acontece quando o PHP acessa memória inválida ao tentar chamar todos os observadores registrados. Sempre que vemos zend_observer_*
no stack trace sem nenhum código New Relic antes do manipulador de sinais, deve surgir alguma dúvida sobre se o PHP é o 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
Você pode testar se o problema é no PHP ou no agente. O PHP tem uma extensão interna chamada zend_test
que possui um observador de teste. Habilitar isso (enquanto desabilita o agente) permite que os caminhos de código OAPI sejam executados por algo diferente do nosso agente. Aqui estão os passos para testar isso:
- Desabilite completamente o agente definindo
newrelic.enabled=0
. Teste aqui para garantir que ele esteja realmente desabilitado. - Habilite a extensão PHP
zend_test
. Isso pode ser feito modificando seu Dockerfile conforme mostrado abaixo. - Defina as configurações
ini
zend_test.observer.enabled=1
ezend_test.observer.observe_all=1
. Isso deve habilitar a API do observador do PHP. - Veja se o problema pode ser reproduzido nessas circunstâncias.
Aqui está um exemplo para o Debian usando uma imagem 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
Aqui está um exemplo usando uma imagem docker Alpine PHP:
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
Aqui está um exemplo da saída phpinfo()
se a extensão estiver instalada e habilitada conforme as instruções acima:
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
Reprodução conhecida e rastreamento da correção
Confira esta página php-src que mostra problemas relacionados a falhas de OAPI e segmentação.
Recomendamos atualizar para a versão mais recente do PHP para receber as correções relevantes assim que forem lançadas.