Что означает «zend_mm_heap corrupted» означает

Внезапно у меня были проблемы с моим приложением, которое у меня никогда не было. Я решил проверить журнал ошибок Apache, и я обнаружил сообщение об ошибке «zend_mm_heap corrupted». Что это значит.

ОС: Fedora Core 8 Apache: 2.2.9 PHP: 5.2.6

После долгих проб и ошибок я обнаружил, что если увеличить значение output_buffering в файле php.ini, эта ошибка исчезнет

Я получал такую ​​же ошибку в PHP 5.5, и увеличение буферизации вывода не помогло. Я тоже не работал с APC, так что это не проблема. Я, наконец, отследил его до opcache , мне просто пришлось отключить его от cli. Для этого была определенная настройка:

 opcache.enable_cli=0 

После переключения поврежденная ошибка zend_mm_heap исчезла.

Если вы находитесь в Linux, попробуйте это в командной строке

 export USE_ZEND_ALLOC=0 

Проверьте на unset() s. Убедитесь, что вы не unset() ссылки на $this (или эквиваленты) в деструкторах, и что unset() s в деструкторах не приводит к тому, что счетчик ссылок на тот же объект падает до 0. Я провел некоторое исследование и обнаружил, что это обычно вызывает кучу коррупции.

Существует отчет об ошибке PHP о поврежденной ошибке zend_mm_heap . См. Комментарий [2011-08-31 07:49 UTC] f dot ardelian at gmail dot com для примера о том, как его воспроизвести.

У меня такое чувство, что все другие «решения» (изменение php.ini , компиляция PHP из источника с меньшим количеством модулей и т. Д.) Просто скрывают проблему.

Это не проблема, которая обязательно разрешима путем изменения параметров конфигурации.

Изменение параметров конфигурации иногда будет иметь положительное влияние, но это может так же легко усугубить ситуацию или вообще ничего не делать.

Характер ошибки таков:

 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { void **mem = malloc(sizeof(char)*3); void *ptr; /* read past end */ ptr = (char*) mem[5]; /* write past end */ memcpy(mem[5], "whatever", sizeof("whatever")); /* free invalid pointer */ free((void*) mem[3]); return 0; } 

Вышеприведенный код может быть скомпилирован с помощью:

 gcc -g -o corrupt corrupt.c 

Выполняя код с valgrind, вы можете увидеть много ошибок памяти, что привело к ошибке сегментации:

 krakjoe@fiji:/usr/src/php-src$ valgrind ./corrupt ==9749== Memcheck, a memory error detector ==9749== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==9749== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==9749== Command: ./corrupt ==9749== ==9749== Invalid read of size 8 ==9749== at 0x4005F7: main (an.c:10) ==9749== Address 0x51fc068 is 24 bytes after a block of size 16 in arena "client" ==9749== ==9749== Invalid read of size 8 ==9749== at 0x400607: main (an.c:13) ==9749== Address 0x51fc068 is 24 bytes after a block of size 16 in arena "client" ==9749== ==9749== Invalid write of size 2 ==9749== at 0x4C2F7E3: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==9749== by 0x40061B: main (an.c:13) ==9749== Address 0x50 is not stack'd, malloc'd or (recently) free'd ==9749== ==9749== ==9749== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==9749== Access not within mapped region at address 0x50 ==9749== at 0x4C2F7E3: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==9749== by 0x40061B: main (an.c:13) ==9749== If you believe this happened as a result of a stack ==9749== overflow in your program's main thread (unlikely but ==9749== possible), you can try to increase the size of the ==9749== main thread stack using the --main-stacksize= flag. ==9749== The main thread stack size used in this run was 8388608. ==9749== ==9749== HEAP SUMMARY: ==9749== in use at exit: 3 bytes in 1 blocks ==9749== total heap usage: 1 allocs, 0 frees, 3 bytes allocated ==9749== ==9749== LEAK SUMMARY: ==9749== definitely lost: 0 bytes in 0 blocks ==9749== indirectly lost: 0 bytes in 0 blocks ==9749== possibly lost: 0 bytes in 0 blocks ==9749== still reachable: 3 bytes in 1 blocks ==9749== suppressed: 0 bytes in 0 blocks ==9749== Rerun with --leak-check=full to see details of leaked memory ==9749== ==9749== For counts of detected and suppressed errors, rerun with: -v ==9749== ERROR SUMMARY: 4 errors from 3 contexts (suppressed: 0 from 0) Segmentation fault 

Если вы не знаете, вы уже поняли, что mem – это память, выделенная кучей; Куча относится к области памяти, доступной программе во время выполнения, потому что программа явно запросила ее (с malloc в нашем случае).

Если вы играете со страшным кодом, вы обнаружите, что не все из этих явно неверных утверждений приводят к ошибке сегментации (фатальная ошибка завершения).

Я явно сделал эти ошибки в примере кода, но те же самые ошибки происходят очень легко в среде с управляемой памятью: если какой-то код не поддерживает refcount переменной (или какого-либо другого символа) правильным способом, например если он свободен, это слишком рано, другой фрагмент кода может читать из уже свободной памяти, если он каким-то образом неправильно хранит адрес, другой фрагмент кода может записывать в недействительную память, он может быть свободен дважды …

Это не проблемы, которые можно отлаживать на PHP, они абсолютно требуют внимания разработчика внутренних компонентов.

Курс действий должен быть:

  1. Откройте отчет об ошибке на http://bugs.php.net
    • Если у вас есть segfault, попробуйте обеспечить обратную трассировку
    • Включите столько информации о конфигурации, которая кажется подходящей, в частности, если вы используете opcache, включите уровень оптимизации.
    • Продолжайте проверять отчет об ошибках на наличие обновлений, может потребоваться дополнительная информация.
  2. Если вы загрузили opcache, отключите оптимизацию
    • Я не выбираю opcache, это здорово, но некоторые из его оптимизаций, как известно, вызывают ошибки.
    • Если это не сработает, даже если ваш код может быть медленнее, попробуйте сначала выгрузить opcache.
    • Если какое-либо из этих изменений изменит или устранит проблему, обновите отчет об ошибке, который вы сделали.
  3. Одновременно отключите все ненужные расширения.
    • Начните включать все ваши расширения отдельно, тщательно тестируя после каждого изменения конфигурации.
    • Если вы обнаружите расширение проблемы, обновите отчет об ошибке с дополнительной информацией.
  4. Прибыль.

Там не может быть никакой прибыли … Я сказал в начале, вы можете найти способ изменить свои симптомы, возиться с конфигурацией, но это чрезвычайно поражает и пропускает, и не помогает в следующий раз, когда вы то же zend_mm_heap corrupted сообщение zend_mm_heap corrupted , существует только так много вариантов конфигурации.

Очень важно, чтобы мы создавали отчеты об ошибках, когда находили ошибки, мы не можем предположить, что следующий человек, попавший в эту ошибку, собирается это сделать … скорее всего, фактическое разрешение никоим образом не является загадочным, если вы сделаете правильные люди осознают эту проблему.

USE_ZEND_ALLOC

Если вы устанавливаете USE_ZEND_ALLOC=0 в среде, это отключает собственный менеджер памяти Zend; Менеджер памяти Zend гарантирует, что каждый запрос имеет свою собственную кучу, что вся память свободна в конце запроса и оптимизирована для выделения кусков памяти только для правильного размера для PHP.

Отключение этой функции отключит эти оптимизации, что более важно, вероятно, создаст утечку памяти, так как существует много кода расширения, который опирается на Zend MM для освобождения памяти для них в конце запроса (tut, tut).

Это может также скрывать симптомы, но системная куча может быть повреждена точно так же, как куча Zend.

Это может показаться более терпимым или менее толерантным, но устранить основную причину проблемы, оно не может .

Возможность отключить его вообще, на благо разработчиков внутренних систем; Никогда не следует развертывать PHP с отключенным Zend MM.

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

Я боролся с этой проблемой в течение недели. Это работало для меня или, по крайней мере, так, как кажется

В php.ini внести эти изменения

 report_memleaks = Off report_zend_debug = 0 

Моя настройка

 Linux ubuntu 2.6.32-30-generic-pae #59-Ubuntu SMP with PHP Version 5.3.2-1ubuntu4.7 

Это не сработало.

Поэтому я попытался использовать тестовый скрипт и попытался записать, где скрипт висит. Я обнаружил, что перед ошибкой был создан экземпляр php-объекта, и для завершения того, что должен был делать объект, потребовалось более 3 секунд, тогда как в предыдущих циклах это заняло максимум 0,4 секунды. Я проверил этот тест несколько раз, и каждый раз тот же. Я думал, вместо того, чтобы каждый раз создавать новый объект (здесь есть длинный цикл), я должен повторно использовать объект. Я тестировал скрипт более десятка раз, и ошибки памяти исчезли!

Для меня ни один из предыдущих ответов не работал, пока я не попытался:

 opcache.fast_shutdown=0 

Это пока работает.

Я использую PHP 5.6 с PHP-FPM и Apache proxy_fcgi, если это важно …

В соответствии с отслеживателем ошибок установите opcache.fast_shutdown=0 . Быстрая остановка использует диспетчер памяти Zend для очистки беспорядка, это отключает это.

Ищите любой модуль, который использует буферизацию, и выборочно отключите его.

Я запускаю PHP 5.3.5 на CentOS 4.8, и после этого я нашел, что eaccelerator нуждается в обновлении.

У меня просто была эта проблема на сервере, который у меня есть, и основной причиной был APC. Я прокомментировал расширение «apc.so» в файле php.ini, перезагрузил Apache, и сайты вернулись обратно.

Я пробовал все выше, и zend.enable_gc = 0 – единственная настройка конфигурации, которая мне помогла.

PHP 5.3.10-1ubuntu3.2 с Suhosin-Patch (cli) (построено: 13 июня 2012 17:19:58)

У меня была эта ошибка с использованием драйвера Mongo 2.2 для PHP:

 $collection = $db->selectCollection('post'); $collection->ensureIndex(array('someField', 'someOtherField', 'yetAnotherField')); 

^^ НЕ РАБОТАЕТ

 $collection = $db->selectCollection('post'); $collection->ensureIndex(array('someField', 'someOtherField')); $collection->ensureIndex(array('yetAnotherField')); 

^^ РАБОТАЕТ! (?!)

На PHP 5.3 после поиска партии это решение, которое сработало для меня:

Я отключил сборку мусора PHP для этой страницы, добавив:

 <? gc_disable(); ?> 

до конца проблемной страницы, из-за которой все ошибки исчезли.

источник .

Я не думаю, что здесь есть один ответ, поэтому я добавлю свой опыт. Я видел эту ту же ошибку вместе со случайными httpd segfaults. Это был сервер cPanel. Симптом, о котором идет речь, был apache, который бы случайно сбросил соединение (никаких данных, полученных в chrome, или соединение не было сброшено в firefox). Они казались случайными – большую часть времени это работало, иногда это не так.

Когда я прибыл на сцену, буферизация вывода была ВЫКЛ. Читая этот поток, который намекал на буферизацию вывода, я включил его (= 4096), чтобы узнать, что произойдет. На этом этапе все они начали показывать ошибки. Хорошо было, что ошибка теперь повторялась.

Я прошел и начал отключать расширения. Среди них, eccellerator, pdo, загрузчик ионных кубов и много, которые выглядели подозрительно, но ни один не помог.

Наконец, я нашел непослушное расширение PHP как «homeloader.so», которое, похоже, является своего рода модулем cPanel-easy-installer. После удаления у меня не было других проблем.

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

  • Сделать ошибку повторяемой (какие условия?) Каждый раз
  • Найти общий фактор
  • Выборочно отключите любые модули PHP, параметры и т. Д. (Или, если вы спешите, отключите их все, чтобы увидеть, помогает ли это, затем выборочно повторно включите их, пока он не сломается снова)
  • Если это не поможет, многие из этих ответов подскажут, что это может быть код, выпущенный. Опять же, ключ должен сделать ошибку повторяемой для каждого запроса, чтобы вы могли сузить ее. Если вы подозреваете, что часть кода делает это, еще раз, после ошибки повторяемость, просто удалите код, пока ошибка не прекратится. Как только он останавливается, вы знаете, что последний фрагмент кода, который вы удалили, был виновником.

В противном случае вы также можете попробовать такие вещи, как:

  • Обновление или перекомпиляция PHP. Надеюсь, что ошибка вызвана вашей проблемой.
  • Переместите ваш код в другую (тестовую) среду. Если это устраняет проблему, что изменилось? Параметры php.ini? Версия PHP? и т.д…

Удачи.

Я думаю, что причиной этой проблемы может быть множество причин. И в моем случае, я назову 2 класса с тем же именем, и один попытается загрузить другой.

 class A {} // in file a.php class A // in file b.php { public function foo() { // load a.php } } 

И это вызывает эту проблему в моем случае.

(Использование laravel framework, запуск php artisan db: семя в реальном режиме)

У меня была эта же проблема, и когда у меня был неправильный IP-адрес session.save_path для сеансов memcached. Исправлена ​​проблема с изменением его на правильный IP-адрес.

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

https://bugs.php.net/bug.php?id=62339

Примечание: эта ошибка очень случайна; по своей природе.

Для меня проблема заключалась в использовании pdo_mysql. Запрос вернул результаты 1960 года. Я попытался вернуть 1900 записей, и он работает. Поэтому проблемой является pdo_mysql и слишком большой массив. Я переписал запрос с оригинальным расширением mysql, и он сработал.

 $link = mysql_connect('localhost', 'user', 'xxxx') or die(mysql_error()); mysql_select_db("db", $link); 

Apache не сообщал о каких-либо предыдущих ошибках.

 zend_mm_heap corrupted zend_mm_heap corrupted zend_mm_heap corrupted [Mon Jul 30 09:23:49 2012] [notice] child pid 8662 exit signal Segmentation fault (11) [Mon Jul 30 09:23:50 2012] [notice] child pid 8663 exit signal Segmentation fault (11) [Mon Jul 30 09:23:54 2012] [notice] child pid 8666 exit signal Segmentation fault (11) [Mon Jul 30 09:23:55 2012] [notice] child pid 8670 exit signal Segmentation fault (11) 

«zend_mm_heap corrupted» означает проблемы с управлением памятью. Может быть вызвано любым модулем PHP. В моем случае была установлена ​​установка APC. В теории могут помочь и другие пакеты, такие как eAccelerator, XDebug и т. Д. Или, если у вас установлены такие модули, попробуйте отключить их.

Я пишу расширение php, а также сталкиваюсь с этой проблемой. Когда я вызываю функцию extern со сложными параметрами из моего расширения, эта ошибка появляется.

Причина в том, что я не выделяю память для параметра (char *) в функции extern. Если вы пишете такое же расширение, обратите внимание на это.

Для меня это был ZendDebugger, который вызвал утечку памяти и уменьшил память MemoryManager.

Я отключил его, и в настоящее время я ищу новую версию. Если я не могу найти его, я переключусь на xdebug …

Поскольку я так и не нашел решения, я решил обновить среду LAMP. Я пошел в Ubuntu 10.4 LTS с PHP 5.3.x. Кажется, это остановило проблему для меня.

В моем случае я забыл следующее в коде:

  ); 

Я играл и забыл об этом в коде здесь и там – в некоторых местах у меня получилось повреждение кучи, а в некоторых случаях просто ошибка «seg fault»:

 [Ср Июн 08 17:23:21 2011] [уведомление] child pid 5720 сигнал выхода Сегментационная ошибка (11)

Я нахожусь на mac 10.6.7 и xampp.

Я также заметил эту ошибку и SIGSEGV при запуске старого кода, который использует «&», чтобы явно принудительно ссылаться на ссылки во время работы в PHP 5.2+.

настройка

 assert.active = 0 

в php.ini помог мне (он отключил утверждения типа в библиотеке zend_mm_heap corrupted а zend_mm_heap corrupted )

Для меня проблема была разбита memcached-демоном, поскольку PHP был настроен для хранения информации о сеансе в memcached. Он ел 100% процессор и играл странно. После перезапуска проблемы с memcached проблема исчезла.

Поскольку ни один из других ответов не рассматривал это, у меня была эта проблема в php 5.4, когда я случайно запускал бесконечный цикл.

Некоторые советы, которые могут помочь кому-то

fedora 20, php 5.5.18

 public function testRead() { $ri = new MediaItemReader(self::getMongoColl('Media')); foreach ($ri->dataReader(10) as $data) { // ... } } public function dataReader($numOfItems) { $cursor = $this->getStorage()->find()->limit($numOfItems); // here is the first place where "zend_mm_heap corrupted" error occurred // var_dump() inside foreach-loop and generator var_dump($cursor); foreach ($cursor as $data) { // ... // and this is the second place where "zend_mm_heap corrupted" error occurred $data['Geo'] = [ // try to access [0] index that is absent in ['Geo'] 'lon' => $data['Geo'][0], 'lat' => $data['Geo'][1] ]; // ... // Generator is used !!! yield $data; } } 

using var_dummp () на самом деле не ошибка, она была размещена только для отладки и будет удалена по производственному коду. Но реальное место, где произошло zend_mm_heap, – второе место.

Я был в такой же ситуации здесь, ничего выше не помогло, и, проверяя более серьезно, я нахожу свою проблему, она состоит в попытке умереть (header ()) после отправки некоторого вывода в буфер, человек, который сделал это в коде, забыл о ресурсах CakePHP и не сделал простых «return $ this-> redirect ($ url)».

Попытка заново изобрести скважину, это была проблема.

Надеюсь, что это поможет кому-то!