Что означает "zend_mm_heap corrupted" означает

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

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

Ответ 1

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

Ответ 2

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

opcache.enable_cli=0

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

Ответ 3

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

export USE_ZEND_ALLOC=0

Ответ 4

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

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

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

#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, вы можете увидеть много ошибок памяти, что привело к ошибке сегментации:

[email protected]:/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: [email protected]@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: [email protected]@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 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, они абсолютно требуют внимания разработчиков-разработчиков.

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

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

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

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

USE_ZEND_ALLOC

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

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

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

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

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

Ответ 5

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

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

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

Ответ 6

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

Ответ 7

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

opcache.fast_shutdown=0

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

Я использую PHP 5.6 с PHP-FPM и Apache proxy_fcgi, если это имеет значение...

Ответ 8

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

Ответ 9

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

В 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  

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

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

Ответ 10

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

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

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

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

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

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

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

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

Удачи.

Ответ 11

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

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

Ответ 12

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

Ответ 13

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

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

Ответ 14

У меня была эта ошибка с использованием драйвера 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')); 

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

Ответ 15

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

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

<? gc_disable(); ?>

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

источник.

Ответ 16

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

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

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

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

Ответ 17

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

Ответ 18

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

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

Примечание: эта ошибка очень случайна; из-за этого характер.

Ответ 19

Для меня проблема заключалась в использовании 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)

Ответ 20

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

Ответ 21

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

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

Ответ 22

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

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

Ответ 23

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

Ответ 24

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

);

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

[Wed Jun 08 17:23:21 2011] [notice] child pid 5720 exit signal Segmentation fault (11)

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

Ответ 25

Настройка

assert.active = 0 

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

Ответ 26

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

Ответ 27

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

Ответ 28

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

Ответ 29

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

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, - второе место.

Ответ 30

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

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

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