php heap fedora php-internals

php - ¿Qué significa "zend_mm_heap corrompido"?



fedora php-internals (30)

De repente, he tenido problemas con mi aplicación que nunca antes había tenido. Decidí consultar el registro de errores de Apache y encontré un mensaje de error que decía "zend_mm_heap dañado". Qué significa esto.

Sistema operativo: Fedora Core 8 Apache: 2.2.9 PHP: 5.2.6


"zend_mm_heap corrupted" significa problemas con la gestión de la memoria. Puede ser causado por cualquier módulo PHP. En mi caso, la instalación de APC funcionó. En teoría, otros paquetes como eAccelerator, XDebug, etc. también pueden ser útiles. O bien, si tiene instalado ese tipo de módulos, intente apagarlos.


Acabo de tener este problema también en un servidor que tengo, y la causa principal fue APC. Comenté la extensión "apc.so" en el archivo php.ini, recargué Apache y los sitios volvieron a funcionar.


Ajuste

assert.active = 0

en php.ini me ayudó (apagó las aserciones de tipo en la biblioteca zend_mm_heap corrupted y zend_mm_heap corrupted fue)


Algunos de los consejos que pueden ayudar a alguien

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; } }

utilizando var_dummp () en realidad no es un error, se colocó solo para la depuración y se eliminará en el código de producción. Pero el lugar real donde se llevó a cabo zend_mm_heap es el segundo lugar.


Busque cualquier módulo que use almacenamiento en búfer y desactívelo selectivamente.

Estoy ejecutando PHP 5.3.5 en CentOS 4.8, y después de hacer esto, encontré que eaccelerator necesitaba una actualización.


Como ninguna de las otras respuestas lo abordó, tuve este problema en php 5.4 cuando accidentalmente ejecuté un ciclo infinito.


Compruebe si hay unset() s. Asegúrese de no unset() referencias a $this (o equivalentes) en destructores y que unset() s en destructores no causan que el recuento de referencias para el mismo objeto caiga a 0. He realizado algunas investigaciones y descubrió que eso es lo que generalmente causa la corrupción del montón.

Hay un informe de error de PHP sobre el error corrompido zend_mm_heap . Vea el comentario [2011-08-31 07:49 UTC] f dot ardelian at gmail dot com para ver un ejemplo sobre cómo reproducirlo.

Tengo la sensación de que todas las otras "soluciones" (cambiar php.ini , compilar PHP desde la fuente con menos módulos, etc.) simplemente ocultan el problema.


Creo que muchas razones pueden causar este problema. Y en mi caso, nombro 2 clases del mismo nombre, y una intentará cargar otra.

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

Y causa este problema en mi caso.

(Usando laravel framework, ejecutando php artisan db: seed en real)


De acuerdo con el rastreador de errores, configure opcache.fast_shutdown=0 . El apagado rápido utiliza el administrador de memoria Zend para limpiar su desorden, esto lo desactiva.


Debido a que nunca encontré una solución para esto, decidí actualizar mi entorno LAMP. Fui a Ubuntu 10.4 LTS con PHP 5.3.x. Esto parece haber detenido el problema para mí.


Después de mucho ensayo y error, descubrí que si aumento el valor de output_buffering en el archivo php.ini, este error desaparece


En PHP 5.3, después de mucho buscar, esta es la solución que funcionó para mí:

Inhabilité la recolección de basura de PHP para esta página agregando:

<? gc_disable(); ?>

hasta el final de la página problemática, que hizo desaparecer todos los errores.

fuente .


En mi caso, la causa de este error fue que una de las matrices se estaba volviendo muy grande. He configurado mi secuencia de comandos para restablecer la matriz en cada iteración y eso solucionó el problema.


En mi caso, me olvidé de seguir en el código:

);

Jugué y lo olvidé en el código aquí y allá. En algunos lugares obtuve corrupción en el montón, algunos casos simplemente olvidan la falla.

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

Estoy en mac 10.6.7 y xampp.


Estaba obteniendo el mismo error en PHP 5.5 y no fue de ayuda aumentar el almacenamiento en búfer de salida. No estaba ejecutando APC tampoco, así que ese no era el problema. Finalmente lo rastreé hasta opcache , simplemente tuve que desactivarlo desde el cli. Había una configuración específica para esto:

opcache.enable_cli=0

Una vez que se cambió, el error corrompido zend_mm_heap desapareció.


Este no es un problema necesariamente solucionable cambiando las opciones de configuración.

Cambiar las opciones de configuración a veces tendrá un impacto positivo, pero también puede empeorar las cosas o no hacer nada en absoluto.

La naturaleza del error es esta:

#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; }

El código anterior se puede compilar con:

gcc -g -o corrupt corrupt.c

Ejecutando el código con valgrind puede ver muchos errores de memoria, que culminan en un error de segmentación:

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

Si no lo sabía, ya se dio cuenta de que mem es memoria asignada en montón; El montón se refiere a la región de memoria disponible para el programa en tiempo de ejecución, porque el programa lo solicitó explícitamente (con malloc en nuestro caso).

Si juegas con el código terrible, encontrarás que no todas esas declaraciones obviamente incorrectas resultan en una falla de segmentación (un error de terminación fatal).

Hice explícitamente esos errores en el código de ejemplo, pero los mismos tipos de errores ocurren muy fácilmente en un entorno administrado por memoria: si algún código no mantiene el recuento de una variable (o algún otro símbolo) de la manera correcta, por ejemplo si sale demasiado pronto, puede leerse otro fragmento de código de la memoria ya liberada, si de alguna manera almacena mal la dirección, otro código puede escribir en la memoria no válida, puede ser liberado dos veces ...

Estos no son problemas que se puedan depurar en PHP, absolutamente requieren la atención de un desarrollador interno.

El curso de acción debe ser:

  1. Abra un informe de error en http://bugs.php.net
    • Si tiene un segfault, intente proporcionar una traza inversa
    • Incluya tanta información de configuración como le parezca apropiada, en particular, si está usando opcache, incluya el nivel de optimización.
    • Siga revisando el informe de errores para las actualizaciones, se puede solicitar más información.
  2. Si tiene opcache cargado, deshabilite las optimizaciones
    • No estoy eligiendo Opcache, es genial, pero se sabe que algunas de sus optimizaciones causan fallas.
    • Si eso no funciona, aunque su código sea más lento, primero intente descargar opcache.
    • Si algo de esto cambia o soluciona el problema, actualice el informe de errores que realizó.
  3. Deshabilita todas las extensiones innecesarias a la vez.
    • Comience a habilitar todas sus extensiones individualmente, realizando pruebas exhaustivas después de cada cambio de configuración.
    • Si encuentra la extensión del problema, actualice su informe de error con más información.
  4. Lucro.

Puede que no haya ninguna ganancia ... Dije al principio, es posible que pueda encontrar una manera de cambiar sus síntomas jugando con la configuración, pero esto es extremadamente impredecible, y no ayuda la próxima vez que tenga el mismo mensaje zend_mm_heap corrupted , solo hay tantas opciones de configuración.

Es muy importante que creemos informes de errores cuando encontremos errores, no podemos suponer que la próxima persona que ataque el error vaya a hacerlo ... lo más probable es que la resolución no sea misteriosa en absoluto, si hace el personas adecuadas conscientes del problema.

USE_ZEND_ALLOC

Si configura USE_ZEND_ALLOC=0 en el entorno, esto desactiva el propio administrador de memoria de Zend; El administrador de memoria de Zend asegura que cada solicitud tenga su propio montón, que toda la memoria esté libre al final de una solicitud, y está optimizada para la asignación de trozos de memoria del tamaño correcto para PHP.

Deshabilitarlo deshabilitará esas optimizaciones, más importante aún, probablemente creará pérdidas de memoria, ya que hay un montón de código de extensión que depende del Zend MM para liberar memoria para ellos al final de una solicitud (tut, tut).

También puede ocultar los síntomas, pero el montón del sistema puede corromperse exactamente de la misma manera que el montón de Zend.

Puede parecer más tolerante o menos tolerante, pero arregla la causa raíz del problema, no puede .

La capacidad de deshabilitarlo es para el beneficio de los desarrolladores internos; Nunca debe implementar PHP con Zend MM deshabilitado.


Estoy escribiendo una extensión de PHP y también encuentro este problema. Cuando invoco una función externa con parámetros complicados de mi extensión, aparece este error.

La razón es que no estoy asignando memoria para un parámetro (char *) en la función extern. Si está escribiendo el mismo tipo de extensión, preste atención a esto.


Estuve en la misma situación aquí, nada me ayudó, y comprobando más seriamente mi problema, consiste en intentar hacer morir (encabezado ()) después de enviar alguna salida al búfer, el hombre que hizo esto en el Código se olvidó de los recursos de CakePHP y no hizo un simple "return $ this-> redirect ($ url)".

Tratando de reinventar el pozo, este era el problema.

¡Espero que esto se relacione con ayudar a alguien!


He intentado todo lo anterior y zend.enable_gc = 0 - la única configuración que me ayudó.

PHP 5.3.10-1ubuntu3.2 con Suhosin-Patch (cli) (construido el: 13 de junio de 2012 17:19:58)


Luché con este tema, durante una semana, Esto funcionó para mí, o al menos así parece

En php.ini hacer estos cambios

report_memleaks = Off report_zend_debug = 0

Mi configuración es

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

Esto no funcionó.

Así que traté de usar un guión de referencia e intenté grabar dónde colgaba el guión. Descubrí que justo antes del error, se creaba una instancia de un objeto php y tardaba más de 3 segundos en completar lo que se suponía que debía hacer el objeto, mientras que en los bucles anteriores tardaba un máximo de 0,4 segundos. Realicé esta prueba varias veces, y cada vez lo mismo. Pensé que en vez de hacer un objeto nuevo cada vez, (hay un ciclo largo aquí), debería volver a usar el objeto. ¡He probado el guión más de una docena de veces hasta ahora y los errores de memoria han desaparecido!


No creo que haya una respuesta aquí, así que agregaré mi experiencia. He visto este mismo error junto con segfaults de httpd aleatorios. Este fue un servidor cPanel. El síntoma en cuestión fue apache reiniciaría la conexión aleatoriamente (No se recibieron datos en Chrome, o la conexión se restableció en Firefox). Estos fueron aparentemente aleatorios, la mayoría de las veces funcionó, otras no.

Cuando llegué a la escena, el buffer de salida estaba en OFF. Al leer este hilo, que insinuaba el almacenamiento en búfer de salida, lo encendí (= 4096) para ver qué sucedería. En este punto, todos comenzaron a mostrar los errores. Esto fue bueno porque el error ahora era repetible.

Pasé y comencé a deshabilitar extensiones. Entre ellos, eaccellerator, pdo, ioncube loader, y muchos que parecían sospechosos, pero ninguno ayudó.

Finalmente encontré la maliciosa extensión PHP como "homeloader.so", que parece ser un tipo de módulo cPanel-easy-installer. Después de la eliminación, no he experimentado ningún otro problema.

En ese sentido, parece que este es un mensaje de error genérico por lo que su kilometraje variará con todas estas respuestas, la mejor medida que puede tomar:

  • Hacer el error repetible (¿qué condiciones?) Cada vez
  • Encuentre el factor común
  • Inhabilite selectivamente cualquier módulo PHP, opciones, etc. (o, si tiene prisa, deshabilítelos para ver si esto ayuda, luego vuelva a habilitarlos selectivamente hasta que se rompa de nuevo)
  • Si esto no ayuda, muchas de estas respuestas sugieren que podría ser un código publicado. Nuevamente, la clave es hacer que el error sea repetible en cada solicitud para que pueda reducirlo. Si sospecha que un fragmento de código está haciendo esto, una vez más, después de que el error sea repetible, simplemente elimine el código hasta que el error se detenga. Una vez que se detiene, usted sabe que el último fragmento de código que eliminó fue el culpable.

Si falla todo lo anterior, también podría intentar cosas como:

  • Actualizar o recompilar PHP. Espero que cualquier error que esté causando tu problema sea solucionado.
  • Mueva su código a un entorno diferente (prueba). Si esto soluciona el problema, ¿qué cambió? Opciones de php.ini? ¿Versión de PHP? etc ...

Buena suerte.


Para mí, el problema fue el daemon de memcached bloqueado, ya que PHP se configuró para almacenar información de sesión en memcached. Estaba comiendo 100% CPU y actuando raro. Después del problema de reinicio de memcached se ha ido.


Para mí, el problema fue usar pdo_mysql. La consulta devolvió los resultados de 1960. Traté de devolver 1900 registros y funciona. Entonces el problema es pdo_mysql y una matriz demasiado grande. Reescribí la consulta con la extensión original de mysql y funcionó.

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

Apache no informó ningún error anterior.

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)


Para mí, fue el ZendDebugger el que causó la pérdida de memoria y provocó que el MemoryManager fallara.

Lo deshabilité y actualmente estoy buscando una versión más nueva. Si no puedo encontrar uno, voy a cambiar a xdebug ...


Para mí, ninguna de las respuestas anteriores funcionó, hasta que intenté:

opcache.fast_shutdown=0

Eso parece funcionar hasta ahora.

Estoy usando PHP 5.6 con PHP-FPM y Apache proxy_fcgi, si eso importa ...


Si está en la caja de Linux, intente esto en la línea de comando

export USE_ZEND_ALLOC=0


Si está utilizando rasgos y el rasgo se carga después de la clase (es decir, el caso de la carga automática), debe cargar el rasgo de antemano.

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

Nota: este error es muy muy aleatorio; debido a su naturaleza


También me he dado cuenta de este error y SIGSEGV al ejecutar un código antiguo que usa ''&'' para forzar explícitamente las referencias mientras se ejecuta en PHP 5.2+.


Tuve este error al usar el controlador Mongo 2.2 para PHP:

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

^^ NO FUNCIONA

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

^^ TRABAJA! (?!)


Tuve este mismo problema y cuando tuve una IP incorrecta para session.save_path para las sesiones de memcached. Cambiarlo a la IP correcta solucionó el problema.