Que signifie "Zend mm tas corrompu"

tout à coup, j'ai eu des problèmes avec mon application que je n'avais jamais eu auparavant. J'ai décidé de vérifier le journal des erreurs D'Apache, et j'ai trouvé un message d'erreur disant "zend_mm_heap corrompu". Qu'est-ce que cela signifie.

OS: Fedora Core 8 Apache: 2.2.9 PHP: 5.2.6

111
demandé sur DaveRandom 2010-02-12 00:49:52

30 réponses

Après beaucoup d'essais et d'erreurs, j'ai trouvé que si j'augmente le output_buffering valeur dans le php.fichier ini, cette erreur disparaît

49
répondu dsmithers 2015-08-06 07:15:16

j'ai eu cette même erreur sous PHP 5.5 et augmenter le tampon de sortie n'a pas aidé. Je ne dirigeais pas APC non plus, donc ce n'était pas le problème. Je l'ai finalement localisé à opcache , j'ai simplement dû le désactiver du cli. Il y avait un réglage spécifique pour cela:

opcache.enable_cli=0

une fois commuté, l'erreur corrompue de zend_mm_heap a disparu.

41
répondu Justin MacLeod 2014-06-18 01:12:08

Si vous êtes sur Linux, essayez ceci sur la ligne de commande

export USE_ZEND_ALLOC=0
39
répondu Hittz 2015-08-06 07:15:43

ce n'est pas un problème qui est nécessairement résolu en changeant les options de configuration.

changer les options de configuration aura parfois un impact positif, mais cela peut tout aussi bien empirer les choses, ou ne rien faire du tout.

la nature de l'erreur est la suivante:

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

le code ci-dessus peut être compilé avec:

gcc -g -o corrupt corrupt.c

L'exécution du code avec valgrind vous pouvez voir beaucoup erreurs de mémoire, aboutissant à un défaut de segmentation:

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 vous ne le saviez pas, vous avez déjà compris que mem est un tas de mémoire allouée; le tas se réfère à la région de mémoire disponible pour le programme à l'exécution, parce que le programme l'a explicitement demandé (avec malloc dans notre cas).

si vous jouez avec le code terrible, vous constaterez que pas tous ces énoncés évidemment incorrects entraîne une segmentation faute (une erreur fatale de terminaison).

j'ai explicitement fait ces erreurs dans le code d'exemple, mais les mêmes types d'erreurs se produisent très facilement dans un environnement de gestion de mémoire: si un code ne maintient pas le refcount d'une variable (ou d'un autre symbole) de la bonne manière, par exemple s'il est libre trop tôt, un autre morceau de code peut lire à partir de la mémoire déjà libre, s'il stocke d'une façon ou d'une autre l'adresse erronée, un autre morceau de code peut écrire à la mémoire invalide, il peut être libre avais deux fois ...

ce ne sont pas des problèmes qui peuvent être débogués en PHP, ils exigent absolument l'attention d'un développeur interne.

Le cours de l'action devrait être:

  1. ouvrir un rapport de bogue sur http://bugs.php.net
    • si vous avez un segfault, essayez de fournir un backtrace
    • Inclure autant de configuration les informations qui semblent appropriées, en particulier si vous utilisez opcache include optimization level.
    • continuez à vérifier le rapport de bogue pour les mises à jour, plus d'informations peuvent être demandées.
  2. si vous avez chargé opcache, désactivez les optimisations
    • Je ne m'en prends pas à opcache, c'est génial, mais certaines de ses optimisations sont connues pour causer des erreurs.
    • si ça ne marche pas, même si votre code peut être plus lent, essayez de décharger opcache en premier.
    • si l'un de ces éléments modifie ou corrige le problème, mettez à jour le rapport de bogue que vous avez fait.
  3. Désactiver tous les extensions inutiles à la fois.
    • commencez à activer toutes vos extensions individuellement, en testant minutieusement après chaque changement de configuration.
    • si vous trouvez l'extension du problème, mettez à jour votre rapport de bogue avec plus d'informations.
  4. sans but Lucratif.

il ne peut y avoir aucun profit ... J'ai dit au début, vous pouvez être en mesure de trouver un moyen de changer vos symptômes en jouant avec la configuration, mais c'est extrêmement hit et manquer, et n'aide pas la prochaine fois que vous avez le même message zend_mm_heap corrupted , il n'y a que tant d'options de configuration.

il est vraiment important que nous créer des rapports de bogues lorsque nous trouvons des bogues, nous ne pouvons pas supposer que la personne suivante va le faire ... plus probablement que non, la résolution réelle n'est en aucun cas mystérieuse, si vous mettez les bonnes personnes au courant du problème.

USE_ZEND_ALLOC

si vous définissez USE_ZEND_ALLOC=0 dans l'environnement, cela désactive le propre gestionnaire de mémoire de Zend; le gestionnaire de mémoire de Zend s'assure que chaque requête a son propre tas, que toute mémoire est libre à la fin de une requête, et est optimisé pour l'allocation de morceaux de mémoire juste la bonne taille pour PHP.

désactiver il va désactiver ces optimisations, plus important encore, il va probablement créer des fuites de mémoire, car il ya beaucoup de code d'extension qui repose sur le Zend MM pour libérer la mémoire pour eux à la fin d'une demande (tut, tut).

il peut aussi Cacher les symptômes, mais le tas de système peut être corrompu exactement de la même manière comme le tas de Zend.

il peut sembler plus tolérant ou moins tolérant, mais fixer la cause profonde du problème, il ne peut pas .

la possibilité de le désactiver du tout, est pour le bénéfice des développeurs internes; vous devriez jamais déployer PHP avec Zend mm désactivé.

29
répondu Joe Watkins 2016-04-01 08:01:32

Check for unset() s. Assurez-vous que vous ne faites pas unset() références au $this (ou des équivalents) dans les destructeurs et que unset() s dans les destructeurs ne font pas le compte de référence au même objet de tomber à 0. J'ai fait des recherches et j'ai découvert que c'est ce qui cause habituellement la corruption de tas.

il y a un rapport de bogue PHP concernant l'erreur de zend_mm_heap. Voir le commentaire [2011-08-31 07:49 UTC] f dot ardelian at gmail dot com pour un exemple sur la façon de de la reproduire.

j'ai le sentiment que toutes les autres" solutions "(changer php.ini , compiler PHP à partir des sources avec moins de modules, etc.) vient masquer le problème.

22
répondu f.ardelian 2011-08-31 08:06:26

dans mon cas, la cause de cette erreur était l'un des tableaux devenait très grand. J'ai mis mon script pour réinitialiser le tableau à chaque itération et que trié le problème.

7
répondu Piotr 2012-04-24 10:10:45

pour moi, aucune des réponses précédentes n'a fonctionné, jusqu'à ce que j'essaie:

opcache.fast_shutdown=0

ça semble marcher jusqu'à présent.

J'utilise PHP 5.6 avec PHP-FPM et Apache proxy_fcgi, si cela compte...

5
répondu Jesús Carrera 2016-02-04 21:32:29

selon le bug tracker, mis opcache.fast_shutdown=0 . L'arrêt rapide utilise le gestionnaire de mémoire Zend pour nettoyer son désordre, ce qui désactive.

5
répondu Taco de Wolff 2016-10-22 17:47:18

j'ai lutté avec ce numéro, pendant une semaine, cela a fonctionné pour moi, ou du moins il semble

dans php.ini faire ces changements

report_memleaks = Off  
report_zend_debug = 0  

mon installation est

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

ça n'a pas marché.

alors j'ai essayé d'utiliser un script benchmark, et j'ai essayé d'enregistrer où le script raccrochait. J'ai découvert que juste avant l'erreur, un objet php a été instancié, et il a fallu plus de 3 quelques secondes pour terminer ce que l'objet était censé faire, alors que dans les boucles précédentes, il a fallu au maximum 0,4 seconde. J'ai fait ce test plusieurs fois, et à chaque fois la même chose. J'ai pensé qu'au lieu de faire un nouvel objet à chaque fois, (il y a une longue boucle ici), je devrais réutiliser l'objet. J'ai testé le script plus d'une douzaine de fois jusqu'à présent, et la mémoire des erreurs ont disparu!

4
répondu sam 2013-10-15 09:25:27

Je ne pense pas qu'il y ait une réponse ici, donc je vais ajouter mon expérience. J'ai vu cette même erreur avec des segfaults aléatoires de httpd. Ce fut un serveur cPanel. Le symptôme en question était qu'apache réinitialisait la connexion au hasard (Aucune donnée reçue dans chrome, ou la connexion était réinitialisée dans firefox). Ceux-ci étaient apparemment aléatoires -- la plupart du temps ça marchait, parfois ça ne marchait pas.

quand je suis arrivé sur la scène, le tampon de sortie était désactivé. Par la lecture de ce fil, que j'ai laissé entendre que le tampon de sortie était activé (=4096) pour voir ce qui se produirait. À ce point, ils tous commencé à montrer les erreurs. C'était bon d'être que l'erreur a maintenant reproductible.

j'ai commencé à désactiver les extensions. Parmi eux, eaccellerator, AOP, ioncube loader, et beaucoup que semblait suspicion, mais aucun n'a aidé.

j'ai enfin trouvé l'extension naughty PHP "homeloader.donc", ce qui semble être une sorte de cPanel-facile-le module d'installation. Après démontage, je n'ai pas connu d'autres problèmes.

Sur cette note, il s'affiche ce message d'erreur générique si votre kilométrage varie avec toutes ces réponses, le meilleur cours d'action que vous pouvez prendre:

  • faire répéter l'erreur (quelles conditions?) chaque fois
  • trouver le facteur commun
  • de manière Sélective désactiver tous les modules, options, etc. de PHP (ou, si vous êtes pressé, les désactiver tous pour voir si cela aide, puis les réactiver sélectivement jusqu'à ce qu'ils se cassent à nouveau)
  • si cela ne sert à rien, beaucoup de ces réponses laissent entendre qu'il pourrait s'agir d'un code libéré. Encore une fois, la clé est de faire l'erreur répétable chaque requête afin que vous puissiez la réduire. Si vous soupçonnez qu'un morceau de code fait cela, encore une fois, après l'erreur est répétable, il suffit de supprimer le code jusqu'à ce que l'erreur s'arrête. Une fois qu'il s'est arrêté, vous savez que le dernier morceau de code que vous avez enlevé était le coupable.

A défaut de tout ce qui précède, vous pouvez aussi essayer des choses comme:

  • mise à niveau ou la recompilation de PHP. Espérons que le bug qui cause votre problème soit corrigé.
  • déplacez votre code dans un environnement différent (test). Si cela résout le problème, ce qui a changé? php.options ini? La version de PHP? etc...

bonne chance.

3
répondu A.B. Carroll 2013-08-22 02:47:45

rechercher tout module qui utilise un tampon et le désactiver de manière sélective.

J'exécute PHP 5.3.5 sur CentOS 4.8, et après avoir fait cela j'ai trouvé qu'eaccelerator avait besoin d'une mise à jour.

2
répondu Scott Davey 2011-02-13 23:33:30

je viens d'avoir ce problème aussi bien sur un serveur que je possède, et la cause racine était APC. J'ai commenté le "apc.ainsi," l'extension dans le php.fichier ini, téléchargement D'Apache, et les sites sont revenus.

2
répondu Vance Lucas 2011-07-05 16:31:32

j'ai tout essayé au-dessus et zend.enable_gc = 0 - le seul réglage de configuration, qui m'a aidé.

PHP 5.3.10-1ubuntu3.2 avec Suhosin-Patch (cli) (construit: Jun 13 2012 17:19:58)

2
répondu Bethrezen 2012-08-28 06:25:43

j'ai eu cette erreur en utilisant le pilote Mongo 2.2 Pour PHP:

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

^^NE FONCTIONNE PAS

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

^ ^ travaux! (?!)

2
répondu hernanc 2012-11-12 18:43:02

sur PHP 5.3, après beaucoup de recherches, c'est la solution qui a fonctionné pour moi:

j'ai désactivé la collecte des ordures PHP pour cette page en ajoutant:

<? gc_disable(); ?>

à la fin de la page problématique, qui a fait disparaître toutes les erreurs.

source .

2
répondu Kuf 2013-03-03 15:02:02

je pense que beaucoup de raison peut causer ce problème. Et dans mon cas, je nomme 2 classes du même nom, et l'une va essayer de charger une autre.

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

et cela cause ce problème dans mon cas.

(à l'Aide de laravel cadre de l'exécution de php artisan db:graine dans la vraie)

2
répondu Yarco 2014-02-09 05:14:37

j'ai eu ce même problème et quand j'ai eu une IP incorrecte pour session.save_path pour memcached sessions. La modification à la bonne adresse IP a résolu le problème.

1
répondu Travis Derouin 2011-06-29 19:30:21

Si vous utilisez des traits et le caractère est chargé après la classe (c'est à dire. le cas de l'autoloading) vous devez charger le trait à l'avance.

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

Note: Ce bug est très aléatoire; en raison de sa nature.

1
répondu srcspider 2012-06-25 08:01:03

pour moi, le problème était d'utiliser pdo_mysql. La requête renvoie les résultats 1960. J'ai essayé de rendre 1900 disques et ça marche. Donc le problème est pdo_mysql et trop grand tableau. J'ai réécrit la requête avec l'extension mysql originale et cela a fonctionné.

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

Apache n'a signalé aucune erreur antérieure.

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)
1
répondu broadband 2012-07-30 08:17:46

"zend_mm_heap corrompu" est synonyme de problèmes avec la gestion de la mémoire. Peut être causé par n'importe quel module PHP. Dans mon cas, installer APC a fonctionné. En théorie d'autres paquets comme eAccelerator, XDebug etc. peut aider trop. Ou, si vous avez ce genre de modules installés, essayez de les éteindre.

1
répondu Muto 2013-11-25 07:12:32

j'écris une extension php et je rencontre également ce problème. Lorsque j'appelle une fonction externe avec des paramètres compliqués de mon extension, cette erreur apparaît.

la raison est que je n'alloue pas de mémoire pour un paramètre(char *) dans la fonction externe. Si vous écrivez le même genre de prolongation, s'il vous plaît prêter attention à cela.

1
répondu cedricliang 2013-12-30 07:38:09

pour moi, C'est le ZendDebugger qui a causé la fuite de mémoire et a forcé le MemoryManager à s'écraser.

Je l'ai désactivé et je suis actuellement à la recherche d'une nouvelle version. Si je n'en trouve pas, je vais passer à xdebug...

0
répondu Structed 2010-08-09 08:37:56

parce que je n'ai jamais trouvé de solution à ce problème, j'ai décidé de mettre à jour mon environnement de lampe. Je suis allé à Ubuntu 10.4 LTS avec PHP 5.3.x. Cela semble avoir arrêté le problème pour moi.

0
répondu bkulyk 2010-10-25 16:44:22

dans mon cas, j'ai oublié le code suivant:

);

j'ai joué et je l'ai oublié dans le code ici et là - bas-dans certains endroits j'ai eu la corruption en tas, certains cas tout simplement ol' seg faute:

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

je suis sur mac 10.6.7 et xampp.

0
répondu dsomnus 2011-06-08 14:41:21

j'ai aussi remarqué cette erreur et celle de SIGSEGV lors de l'exécution de l'ancien code qui utilise '&' pour forcer explicitement les références tout en l'exécutant en PHP 5.2+.

0
répondu Phillip Whelan 2012-10-18 05:47:32

Réglage

assert.active = 0 

en php.ini a aidé pour moi (il éteint les assertions de type dans php5UTF8 bibliothèque et zend_mm_heap corrupted est parti)

0
répondu Vasiliy 2012-10-20 15:23:19

pour moi le problème a été crashed memcached daemon, comme PHP a été configuré pour stocker des informations de session dans memcached. Il mangeait 100% cpu et agissait bizarrement. Après memcached, le problème de redémarrage a disparu.

0
répondu Justinas Jaronis 2013-05-10 07:36:47

Car aucune des autres réponses adressées, j'ai eu ce problème en php 5.4 quand j'ai accidentellement couru une boucle infinie.

0
répondu Trenton Maki 2014-08-29 21:31:26

Quelques conseils qui aide à quelqu'un

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

utilisant var_dummp () en fait pas une erreur, il a été placé juste pour le débogage et sera supprimé sur le code de production. Mais l'endroit où zend_mm_heap s'est produit est le deuxième.

0
répondu lexand 2014-11-10 08:34:40

j'étais dans la même situation ici, rien au-dessus n'a aidé, et en vérifiant plus sérieusement je trouve mon problème, il consiste en try do die(header()) après avoir envoyé une sortie à buffer, l'homme qui a fait cela dans le Code a oublié les ressources de CakePHP et n'a pas fait un simple"return $this - >redirect($url)".

essayer de réinventer le puits, c'était le problème.

j'espère que ce rapport aider quelqu'un!

0
répondu Newton Pasqualini Filho 2015-03-27 21:09:26