De repente, tenho tido problemas com meu aplicativo que nunca tive antes. Decidi verificar o log de erros do Apache e encontrei uma mensagem de erro dizendo "zend_mm_heap corrompido". O que isto significa.
SO: Fedora Core 8 Apache: 2.2.9 PHP: 5.2.6
De repente, tenho tido problemas com meu aplicativo que nunca tive antes. Decidi verificar o log de erros do Apache e encontrei uma mensagem de erro dizendo "zend_mm_heap corrompido". O que isto significa.
SO: Fedora Core 8 Apache: 2.2.9 PHP: 5.2.6
Respostas:
Após muitas tentativas e erros, descobri que, se eu aumentar o output_buffering
valor no arquivo php.ini, esse erro desaparece
Este não é um problema necessariamente solucionável ao alterar as opções de configuração.
A alteração das opções de configuração às vezes terá um impacto positivo, mas pode facilmente piorar as coisas ou não fazer nada.
A natureza do erro é 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;
}
O código acima pode ser compilado com:
gcc -g -o corrupt corrupt.c
Ao executar o código com o valgrind, você pode ver muitos erros de memória, culminando em uma falha de segmentação:
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
Se você não sabia, você já descobriu que mem
é a memória alocada por heap; A pilha se refere à região de memória disponível para o programa em tempo de execução, porque o programa solicitou explicitamente (com malloc no nosso caso).
Se você brincar com esse código terrível, descobrirá que nem todas essas instruções obviamente incorretas resultam em uma falha de segmentação (um erro fatal de terminação).
Eu cometi explicitamente esses erros no código de exemplo, mas os mesmos tipos de erros ocorrem com muita facilidade em um ambiente gerenciado por memória: se algum código não mantiver a contagem de ref de uma variável (ou outro símbolo) da maneira correta, por exemplo se for liberado cedo demais, outro trecho de código poderá ler a partir da memória já liberada; se, de alguma forma, armazenar o endereço errado, outro trecho de código for gravado na memória inválida, poderá ser liberado duas vezes ...
Estes não são problemas que podem ser depurados no PHP, eles exigem absolutamente a atenção de um desenvolvedor interno.
O curso de ação deve ser:
Pode não haver nenhum lucro ... Eu disse no início, você pode encontrar uma maneira de alterar seus sintomas mexendo com a configuração, mas isso é extremamente difícil de entender e não ajuda na próxima vez que você tiver Na mesma zend_mm_heap corrupted
mensagem, existem apenas tantas opções de configuração.
É realmente importante criar relatórios de bugs quando encontrarmos bugs, não podemos presumir que a próxima pessoa a acertá-lo fará isso ... mais provavelmente do que não, a resolução real não é de forma alguma misteriosa, se você fizer o pessoas certas conscientes do problema.
Se você definir USE_ZEND_ALLOC=0
no ambiente, isso desabilitará o gerenciador de memória do Zend; O gerenciador de memória do Zend garante que cada solicitação tenha seu próprio heap, que toda a memória seja liberada no final de uma solicitação e seja otimizada para a alocação de blocos de memória do tamanho certo para o PHP.
Desabilitá-lo desabilitará essas otimizações, o que é mais importante, provavelmente criará vazamentos de memória, pois há muitos códigos de extensão que dependem do Zend MM para liberar memória para eles no final de uma solicitação (tut, tut).
Também pode ocultar os sintomas, mas a pilha do sistema pode ser corrompida exatamente da mesma maneira que a pilha do Zend.
Pode parecer mais tolerante ou menos tolerante, mas corrija a causa raiz do problema, não pode .
A capacidade de desativá-lo é para o benefício de desenvolvedores internos; Você nunca deve implantar o PHP com o Zend MM desativado.
Eu estava recebendo esse mesmo erro no PHP 5.5 e aumentar o buffer de saída não ajudou. Eu também não estava executando o APC, então esse não era o problema. Eu finalmente o localizei no opcache , eu simplesmente tive que desativá-lo do CLI. Havia uma configuração específica para isso:
opcache.enable_cli=0
Uma vez trocado, o erro corrompido zend_mm_heap desapareceu.
Se você estiver no Linux, tente isso na linha de comando
export USE_ZEND_ALLOC=0
/etc/apache2/envvars
se você estiver executando isso no servidor ubuntu com o apache e o php instalados no ppas (apt). O PHP 7.0-RC4 começou a lançar esse erro quando eu o instalei no repositório do ondrej.
set USE_ZEND_ALLOC=0
Verifique se há unset()
s. Certifique-se de não unset()
referenciar os $this
(ou equivalentes) nos destruidores e isso unset()
não significa que a contagem de referências para o mesmo objeto caia para 0. Eu fiz algumas pesquisas e descobri que é o que geralmente causa o heap corrupção.
Há um relatório de bug do PHP sobre o erro corrompido do zend_mm_heap . Veja o comentário [2011-08-31 07:49 UTC] f dot ardelian at gmail dot com
para um exemplo de como reproduzi-lo.
Eu tenho a sensação de que todas as outras "soluções" (alterar php.ini
, compilar o PHP da fonte com menos módulos etc.) apenas escondem o problema.
Para mim, nenhuma das respostas anteriores funcionou, até que tentei:
opcache.fast_shutdown=0
Isso parece funcionar até agora.
Estou usando o PHP 5.6 com PHP-FPM e Apache proxy_fcgi, se isso importa ...
No meu caso, a causa desse erro foi uma das matrizes que estava se tornando muito grande. Eu configurei meu script para redefinir a matriz em todas as iterações e isso resolveu o problema.
Conforme o rastreador de bugs, defina opcache.fast_shutdown=0
. O desligamento rápido usa o gerenciador de memória Zend para limpar sua bagunça, isso desativa isso.
Eu não acho que exista uma resposta aqui, então adicionarei minha experiência. Eu vi esse mesmo erro, juntamente com segfaults httpd aleatórios. Este era um servidor cPanel. O sintoma em questão era que o apache redefiniria a conexão aleatoriamente (nenhum dado recebido no chrome ou a conexão foi redefinida no firefox). Estes eram aparentemente aleatórios - na maioria das vezes funcionava, às vezes não.
Quando cheguei à cena, o buffer de saída estava DESLIGADO. Ao ler este tópico, que sugeria o buffer de saída, liguei-o (= 4096) para ver o que aconteceria. Nesse ponto, todos começaram a mostrar os erros. Isso foi bom porque o erro agora era repetível.
Eu passei e comecei a desativar as extensões. Entre eles, eaccellerator, pdo, ioncube loader, e muitos que pareciam suspeitos, mas nenhum ajudou.
Finalmente encontrei a extensão impertinente do PHP como "homeloader.so", que parece ser algum tipo de módulo cPanel-easy-installer. Após a remoção, não tive outros problemas.
Nessa nota, parece que esta é uma mensagem de erro genérica, portanto sua milhagem varia com todas essas respostas, o melhor curso de ação que você pode executar:
Na falta de todas as opções acima, você também pode tentar coisas como:
Boa sorte.
Eu lutei com esse problema, por uma semana, Isso funcionou para mim, ou pelo menos parece que
Em php.ini
fazer essas alterações
report_memleaks = Off
report_zend_debug = 0
Minha configuração é
Linux ubuntu 2.6.32-30-generic-pae #59-Ubuntu SMP
with PHP Version 5.3.2-1ubuntu4.7
Isso não funcionou.
Então, tentei usar um script de referência e tentei gravar onde o script estava desligado. Descobri que, pouco antes do erro, um objeto php era instanciado e demorava mais de 3 segundos para concluir o que o objeto deveria fazer, enquanto nos loops anteriores levava no máximo 0,4 segundos. Eu executei esse teste algumas vezes e sempre o mesmo. Pensei que, em vez de criar um novo objeto toda vez (há um longo ciclo aqui), eu deveria reutilizar o objeto. Testei o script mais de uma dúzia de vezes até agora e os erros de memória desapareceram!
Procure por qualquer módulo que use buffer e desative-o seletivamente.
Estou executando o PHP 5.3.5 no CentOS 4.8 e, depois disso, descobri que o eaccelerator precisava de uma atualização.
Eu também tive esse problema em um servidor que possuo e a causa raiz foi a APC. Comentei a extensão "apc.so" no arquivo php.ini, recarreguei o Apache e os sites voltaram.
Eu tive esse erro ao usar o driver Mongo 2.2 para PHP:
$collection = $db->selectCollection('post');
$collection->ensureIndex(array('someField', 'someOtherField', 'yetAnotherField'));
^^ NÃO FUNCIONA
$collection = $db->selectCollection('post');
$collection->ensureIndex(array('someField', 'someOtherField'));
$collection->ensureIndex(array('yetAnotherField'));
^^ FUNCIONA! (?!)
foreach(selectCollection()->find()) { $arr = .. }
No PHP 5.3, após muitas pesquisas, esta é a solução que funcionou para mim:
Eu desativado a coleta de lixo PHP para esta página, adicionando:
<? gc_disable(); ?>
até o final da página problemática, que fez todos os erros desaparecerem.
fonte .
Eu acho que muitas razões podem causar esse problema. E no meu caso, eu nomeio 2 classes com o mesmo nome, e uma tentará carregar outra.
class A {} // in file a.php
class A // in file b.php
{
public function foo() { // load a.php }
}
E isso causa esse problema no meu caso.
(Usando o framework laravel, executando o php artisan db: seed em real)
Eu tive esse mesmo problema e quando tive um IP incorreto para session.save_path para sessões em cache. Mudar para o IP correto corrigiu o problema.
Se você estiver usando características e a característica for carregada após a aula (por exemplo, o caso do carregamento automático), será necessário carregar a característica antecipadamente.
https://bugs.php.net/bug.php?id=62339
Nota: este bug é muito, muito aleatório; devido à sua natureza.
Para mim, o problema estava usando pdo_mysql. A consulta retornou 1960 resultados. Tentei devolver 1900 registros e funciona. Então, o problema é pdo_mysql e uma matriz muito grande. Eu reescrevi a consulta com extensão mysql original e funcionou.
$link = mysql_connect('localhost', 'user', 'xxxx') or die(mysql_error());
mysql_select_db("db", $link);
O Apache não relatou nenhum erro 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)
"zend_mm_heap corrompido" significa problemas com o gerenciamento de memória. Pode ser causado por qualquer módulo PHP. No meu caso, a instalação da APC deu certo. Em teoria, outros pacotes como eAccelerator, XDebug etc. podem ajudar também. Ou, se você tiver esse tipo de módulo instalado, tente desativá-lo.
Estou escrevendo uma extensão php e também encontro esse problema. Quando eu chamo uma função externa com parâmetros complicados do meu ramal, esse erro aparece.
O motivo é não alocar memória para um parâmetro (char *) na função externa. Se você estiver escrevendo o mesmo tipo de extensão, preste atenção nisso.
No meu caso, esqueci o seguinte no código:
);
Eu brinquei e esqueci no código aqui e ali - em alguns lugares eu tenho corrupção de heap, alguns casos simplesmente uma falha de seg ':
[Qua Jun 08 17:23:21 2011] [aviso] sinal de saída do criança pid 5720 Falha na segmentação (11)
Estou no mac 10.6.7 e xampp.
Eu também notei esse erro e os SIGSEGVs ao executar o código antigo que usa '&' para forçar explicitamente as referências ao executá-lo no PHP 5.2+.
Para mim, o problema foi o daemon do memcached com falha, pois o PHP foi configurado para armazenar informações da sessão no memcached. Ele estava comendo 100% da CPU e agindo de forma estranha. Após o problema de reinicialização do memcached ter desaparecido.
Como nenhuma das outras respostas o abordou, tive esse problema no php 5.4 quando acidentalmente executei um loop infinito.
Algumas dicas que podem ajudar alguém
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;
}
}
usando var_dummp () na verdade não é um erro, ele foi colocado apenas para depuração e será removido no código de produção. Mas o lugar real onde o zend_mm_heap aconteceu foi o segundo lugar.
Eu estava na mesma situação aqui, nada acima ajudou, e verificando com mais seriedade eu acho o meu problema, consiste em tentar morrer (cabeçalho ()) depois de enviar alguma saída para o buffer, o homem que fez isso no Código esqueceu os recursos do CakePHP e não fez um simples "return $ this-> redirect ($ url)".
Tentando reinventar o poço, esse era o problema.
Espero que esse relacionamento ajude alguém!
USE_ZEND_ALLOC=0
obter o rastreamento de pilha no log de erros. E encontrei o bug/usr/sbin/httpd: corrupted double-linked list
. Descobri que, comentando,opcache.fast_shutdown=1
funcionava para mim.