Mandelbug é um tipo de erro de software cujo comportamento é caótico e depende de múltiplos fatores: estado da memória, ordem de execução das threads, condições externas. O nome vem do matemático Benoit Mandelbrot, criador da teoria dos fractais, onde a menor mudança nas condições iniciais leva a um resultado radicalmente diferente. De acordo com Wikipédia (2026), Mandelbug é um dos tipos de defeitos mais difíceis de diagnosticar porque não pode ser reproduzido com um cenário fixo.
Pontos Principais
Mandelbug é um bug de software com comportamento não linear e caótico. Ao contrário do Bohrbug, que se reproduz de forma estável com os mesmos dados de entrada, o Mandelbug pode aparecer em uma sessão e estar completamente ausente em outra sob as mesmas condições externas.
O termo foi introduzido por Jim Gray e Andreas Reuter em 1993 como parte de uma classificação de bugs de software. Mandelbug recebeu esse nome em homenagem a Benoit Mandelbrot, o matemático que descobriu os conjuntos fractais, onde o comportamento do sistema depende exponencialmente das condições iniciais.
O principal perigo do Mandelbug reside na sua imprevisibilidade. Um testador pode executar o mesmo cenário cinquenta vezes, e o bug só aparecerá na quinquagésima primeira vez — ou não aparecerá. Isso cria uma falsa sensação de estabilidade do sistema.
De acordo com a classificação do livro “Transaction Processing: Concepts and Techniques”, Mandelbug é um defeito que não satisfaz a condição de determinismo. Seu comportamento depende de fatores que o desenvolvedor não pode controlar: ordem de escalonamento das threads, fragmentação de memória, cache.
O nome Mandelbug vem de Benoit Mandelbrot, o matemático que introduziu o conceito de fractais e estudou sistemas caóticos. O conjunto de Mandelbrot demonstra uma propriedade impressionante: mudanças infinitamente pequenas nas condições iniciais levam a resultados fundamentalmente diferentes.
Gray e Reuter traçaram uma analogia direta: assim como o fractal de Mandelbrot é sensível às condições iniciais, o Mandelbug é sensível ao estado do sistema no momento da execução. Uma mudança na ordem de alocação de memória ou no quantum de escalonamento das threads — e o bug desaparece ou aparece.
No jargão profissional, Mandelbug também é chamado de “bug fantasma” ou “bug intermitente”. Ele é o principal inimigo dos engenheiros de QA, pois não se submete à metodologia padrão de “reproduzir — reportar — verificar correção”.
Mandelbug possui um conjunto único de propriedades que o distinguem de todos os outros tipos de bugs de software. Vamos examinar cada uma delas.
O comportamento do Mandelbug é não linear. Ele pode não se manifestar milhares de vezes e, de repente, aparecer sob condições aparentemente idênticas. Essa propriedade o torna praticamente indetectável durante os testes funcionais.
Mandelbug depende do estado interno do sistema: tamanho do heap, ordem de alocação de objetos, ocupação do cache da CPU. Até mesmo adicionar um printf de depuração pode alterar os tempos e “curar” o bug, transformando-o em Heisenbug.
O termo “Efeito borboleta” se aplica totalmente ao Mandelbug. Alterar uma linha de código em um módulo completamente diferente pode eliminar ou, inversamente, causar Mandelbug em uma parte não relacionada da aplicação devido a mudanças nos padrões de alocação de memória.
As causas do Mandelbug estão relacionadas à execução concorrente e ao comportamento não determinístico dos sistemas computacionais modernos.
Uma condição de corrida clássica — quando duas threads acessam simultaneamente um recurso compartilhado sem sincronização. O resultado depende de qual thread executa primeiro, e a ordem de execução não é garantida pelo sistema operacional.
O cache do processador e o cache do navegador podem armazenar dados desatualizados. Se uma aplicação depende de um valor em cache que não é mais relevante, ocorre um Mandelbug — um erro que só se manifesta com cache “frio” ou “quente”.
Algumas construções da linguagem (por exemplo, variáveis não inicializadas em C/C++) levam a comportamento indefinido. O compilador pode gerar código diferente dependendo do nível de otimização, flags de compilação e versão do compilador.
Encontrar Mandelbug requer uma abordagem sistemática e ferramentas especializadas. Métodos convencionais de depuração não funcionam aqui porque o bug não é reproduzível sob demanda.
O registro detalhado é a única maneira de capturar Mandelbug. Cada thread deve registrar seu estado, carimbos de data/hora e ordem das operações. Após uma falha, os registros são analisados para identificar padrões.
Testes de carga com operações repetidas aumentam a probabilidade de manifestação do Mandelbug. Quanto mais iterações, maior a chance de que uma combinação rara de condições leve a uma falha.
ThreadSanitizer, Helgrind e outros analisadores de corrida de threads podem detectar potenciais Mandelbugs sem realmente reproduzi-los. Eles analisam o código estaticamente e encontram lugares onde condições de corrida podem ocorrer.
// Potential Mandelbug: race condition on shared counter
int counter = 0;
void increment() {
// Two threads may read counter at the same time
counter++; // race condition here
}
Neste exemplo, Mandelbug pode se manifestar apenas sob uma combinação específica de circunstâncias — quando ambas as threads chamam increment() simultaneamente. Em 99% dos casos, o código funciona corretamente, criando uma falsa sensação de segurança.
Desenvolvedores iniciantes frequentemente confundem Mandelbug e Heisenbug. Embora ambos os tipos pertençam a bugs instáveis, há uma diferença fundamental entre eles.
| Critério | Mandelbug | Heisenbug |
|---|---|---|
| Causa da instabilidade | Estado caótico do sistema | A própria depuração altera o comportamento |
| Comportamento sem depurador | Manifesta-se raramente, mas imprevisivelmente | Manifesta-se de forma estável até tentar depurar |
| Comportamento no depurador | Pode desaparecer ou mudar | Quase garantido que desaparece |
| Causa típica | Condição de corrida, temporização | Otimização do compilador, temporizadores |
| Ferramenta de detecção | ThreadSanitizer, logs | Análise de dumps, desmontador |
Mandelbug é caótico por natureza, enquanto Heisenbug é determinístico mas muda de comportamento sob observação. A diferença é importante para escolher uma estratégia de depuração.
Vejamos um Mandelbug típico em uma aplicação Android relacionado a uma corrida de threads ao trabalhar com SharedPreferences.
public class UserPreferences {
private final SharedPreferences prefs;
public synchronized void updateScore(int delta) {
int current = prefs.getInt("score", 0);
current += delta;
prefs.edit().putInt("score", current).apply();
}
}
À primeira vista, o código está correto: o método está sincronizado. No entanto, SharedPreferences é um singleton dentro do processo, e a sincronização não protege contra chamadas paralelas de diferentes threads que obtiveram o mesmo valor de current antes que uma delas pudesse escrever um novo valor. Como resultado, um incremento é perdido.
Este Mandelbug pode não se manifestar por semanas até que duas threads acidentalmente chamem updateScore simultaneamente com diferença mínima de tempo. Após a detecção, a correção é trivial — usar uma operação atômica ou um banco de dados com transações.
Perguntas Frequentes
Mandelbug é uma subclasse de bugs intermitentes com natureza caótica pronunciada. Um bug intermitente comum pode ter uma causa compreensível mas rara, enquanto Mandelbug exibe uma dependência não linear de muitos fatores difíceis de identificar.
A dificuldade de reproduzir Mandelbug decorre de sua dependência de detalhes microscópicos do estado do sistema: ordem de alocação de memória, escalonamento de threads pelo sistema operacional, ocupação do cache da CPU. Esses fatores não podem ser controlados a partir do código da aplicação.
As ferramentas mais eficazes: ThreadSanitizer (TSan), Valgrind Helgrind para C/C++, para Java — utilitários de análise de corrida (Intel Inspector, FindBugs), para código multithread — analisadores estáticos e testes de estresse com randomização de tempo.
Sim, problemas de memória são uma das principais causas do Mandelbug. Vazamentos de memória, fragmentação do heap, uso após liberação (use-after-free) e memória não inicializada criam condições onde o comportamento do programa se torna caótico e imprevisível.
A imutabilidade dos dados é a melhor proteção. Se os dados não puderem ser alterados após a criação, as corridas de threads são eliminadas. Também ajudam: contratos explícitos de sincronização, tipos atômicos, isolamento do acesso concorrente atrás de bloqueios e filas de mensagens.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também