Ошибка сегментации PHPUnit

Когда тест PHPUnit не работает нормально в моей dev-блоке (Linux Mint), он вызывает «Ошибка сегментации» в поле «Непрерывная интеграция» (Centos). Обе машины работают с одной и той же версией PHPUnit. В моем блоке dev работает PHP 5.3.2-1ubuntu4.9, а CI – PHP 5.2.17. Однако я предпочел бы оставить обновление PHP как последнее средство.

По этой теме: PHPUnit получает ошибку сегментации Я попытался отключить / переустановить Xdebug. У меня нет инсталяции.

В ящике CI в настоящее время у меня есть только два расширения: dom из php-xml (требуется для phpunit) и memcache (требуется для моей рамки), все остальные отключены.

Рядом с тем, что предложил cweiske, если обновление PHP не является для вас вариантом, и у вас есть проблемы с поиском источника segfault, вы можете использовать отладчик, чтобы узнать больше.

Вы можете запустить gdb таким образом, чтобы отладить сессию PHPUnit:

gdb --args php /usr/bin/phpunit quiz_service_Test.php 

Затем введите r для запуска программы и / или установки переменных среды.

 set env MALLOC_CHECK_=3 r 

Вы могли бы также рассмотреть возможность установки отладочных символов для PHP в системе, чтобы получить лучшие результаты для отладки. gdb проверяет это при запуске для вас и оставляет уведомление, как вы можете это сделать.

У меня возникла проблема с PHPUnit segfaulting и у меня возникли проблемы с поиском ответа, поэтому, надеюсь, это поможет кому-то с той же проблемой позже.

PHPUnit был segfault, но только:

  • Если произошла ошибка (или более одного)
  • После того, как все тесты были выполнены, но до того, как были напечатаны ошибки

Через некоторое время я понял, что это произошло из-за сбоев в тестах, которые использовали поставщики данных, и особенно для поставщиков данных, которые передавали объекты с большим количеством рекурсивных ссылок. Колокол наконец-то ушел, и я сделал кое-какие операции: проблема в том, что, когда вы используете поставщиков данных, а тест терпит неудачу, PHPUnit пытается создать строковое представление предоставленных аргументов для описания отказа, чтобы сообщить вам, что не удалось, но это является проблематичным, когда один из аргументов имеет некоторую бесконечную рекурсию. Фактически, что делает PHPUnit в PHPUnit_Framework_TestCase::dataToString() (около строки 1612), распечатывают все аргументы, предоставленные поставщиком данных, используя print_r , что вызывает segfault, когда PHP пытается создать строковое представление бесконечно рекурсивного объекта.

Решение, к которому я пришел, было:

  1. Используйте один базовый класс для всех моих тестовых классов (которые, к счастью, я уже делал)
  2. Переопределите dataToString() в моем базовом классе тестов, чтобы проверить эти типы объектов в массиве данных (что возможно в моем случае, потому что я знаю, как выглядят эти объекты). Если объект присутствует, я возвращаю некоторое специальное значение, если не просто передаю его методу родительского метода.

Когда вы получите segfault, обновите свой PHP до последней версии. Не только последний в вашем диспетчере пакетов, но и последний доступный на php.net. Если он все еще неисправен, вы уверены, что проблема еще не исправлена ​​в самом PHP. Не беспокойтесь, пытаясь избавиться от segfault в старой версии PHP, потому что он может быть исправлен уже в более новой версии.

Следующий шаг – найти проблему. Сделайте свой тест все меньше и меньше, пока вы не сможете удалить что-либо (но оно все еще сохраняется). Если у вас есть это, переместите тест в автономный php-скрипт, который segfaults. Теперь у вас есть тестовый скрипт для вашей ошибки в отладчике ошибок PHP.

У меня была аналогичная проблема, и, отключив коллактор

PHPStorm => Изменить конфигурацию => Вариант интерпретатора: -d zend.enable_gc = 0

Или, если вы запускаете свои тесты из командной строки, вы можете попробовать добавить:

-d zend.enable_gc = 0

У меня была такая же проблема, и я мог бы прибить ее, чтобы попытаться написать переменную класса, которая не была определена:

Мой класс (это класс cakePHP), который вызвал ошибку сегментации:

 class MyClass extends AppModel { protected $classVariableOne; public function __construct($id = false, $table = null, $ds = null) { parent::__construct($id, $table, $ds); $this->classVariableOne =& ClassRegistry::init('ClassVariableOne'); // This line caused the segmentation fault as the variable doesn't exists $this->classVariableTwo =& ClassRegistry::init('ClassVariableTwo'); } } 

Я исправил его, добавив вторую переменную:

 class MyClass extends AppModel { protected $classVariableOne; protected $classVariableTwo; // Added this line public function __construct($id = false, $table = null, $ds = null) { parent::__construct($id, $table, $ds); $this->classVariableOne =& ClassRegistry::init('ClassVariableOne'); $this->classVariableTwo =& ClassRegistry::init('ClassVariableTwo'); } } 

Я попал в ту же проблему. Я обновил PHPUnit до версии 4.1 (чтобы запустить тесты), и он смог показать мне объект, как указал Исаак.

Итак, если вы дойдете до этой же проблемы, перейдите на PHPUnit> = 4.1, и вы сможете увидеть эту ошибку вместо получения сообщения «Ошибка сегментации».

Я продолжал получать Segmentation fault: 11 при запуске PHPUnit с охватом кода. После выполнения трассировки стека сегментации я обнаружил, что следующее вызвало ошибку ошибки сегментации:

 Program received signal SIGSEGV, Segmentation fault. 0x0000000100b8421a in xdebug_path_info_get_path_for_level () from /usr/lib/php/extensions/no-debug-non-zts-20121212/xdebug.so 

Я заменил свой текущий xdebug.so на путь выше с последней версией из пакета удаленной отладки Komodo xdebug.so соответствующего загруженного пакета с версией PHP, которая у меня есть (для меня это 5.5), и все сработало.

Следующее исправление аналогичной проблемы для меня (когда вывод backtrace gdb включал libcurl.so и libcrypto.so ):

disable /etc/php.d/pgsql.ini :

 ; Enable pgsql extension module ; extension=pgsql.so 

отредактируйте /etc/php.d/curl.ini чтобы убедиться, что pgsql.so включен до curl:

 ; Enable curl extension module extension=pgsql.so extension=curl.so curl.cainfo=/home/statcounter/include/config/cacert.pem 

В дополнение к https://stackoverflow.com/a/38789046/246790, который мне очень помог:

Вы можете использовать функцию PHP gc_disable();

Я поместил его в свой код начальной загрузки PHPUnit с помощью ini_set('memory_limit', -1);

Это связано с не расширением кода. В моем случае у меня были эти два файла

  1. Прецедент
  2. Пример теста

В тестовом примере существует метод под названием createApplication . Просто оставьте его пустым.
В примере теста вы можете создать метод и заполнить с помощью $ this-> assertTrue (true)

Вышеуказанная базовая установка надеется, что вы сможете расширить требования по мере необходимости.