Onde Está Meu Coredump?

Fui motivado a escrever esse artigo devido a uma consultoria que realizei ultimamente. Estava desenvolvendo uma aplicação para um software embarcado e tive um segmentation fault, o qual não consegui detectar através de mensagens de log aplicados a meu código (o problema tinha relação a acesso mútuo a uma determinada variável global por uma infinidade de threads). Para solucionar isso, decidi gerar um core dump para encontrar o ponto exato do crash.

Se você buscar no Google por “core dump, você terá a seguinte resposta:

A core dump is the printing or the copying to a more permanent medium (such as a hard disk) the contents of random access memory (RAM) at one moment in time. One can think of it as a full-length “snapshot” of RAM. A core dump is taken mainly for the purpose of debugging a program.

Traduzindo: É uma impressão de uma certa região da RAM em um determinado tempo, ou seja, um “snapshot” da RAM. No caso, eu gostaria de um “snapshot” exatamente no momento em que ocorreu crash de uma determinada aplicação.

Para gerar o core dump, devemos fazer algumas configurações no Kernel. Primeiro no arquivo /proc/sys/kernel/ nós podemos encontrar os arquivos core_pattern, core_pipe_limit e core_uses_pid:

  • core_pattern indica o nome do arquivo do core dump. Ele tem vários formatadores , como %e e %p para incluir o nome do executável e/ou o seu PID;
  • core_pipe_limit: Ao conduzir o dump de um programa, o kernel deve manter as informações em /proc/< pid>/ por um tempo , até que o programa captura as informações e sai. Se de alguma forma o processo não sair, os próximos core dump serão bloqueados. Este atributo controla quantos core dumps podem ser canalizados em paralelo;
  • core_uses_pid: Adiciona o PID do processo no arquivo de core dump caso seu valor seja diferente de zero (no caso de não adicionar o %p no core_pattern);

Em meu caso eu utilizei o seguinte comando para adicionar o local de geração. Note que adicionei em um local onde montei um pendrive, pois os arquivos de core dump são bem pesados (em torno de 50MB):

echo '/mnt/sda1/core_%e.%p' | sudo tee /proc/sys/kernel/core_pattern

Agora, eu precisava gerar um executável que quando tivesse um segmentation fault gerasse o core dump. Para isso adicionei a flag ‘-g’ na linha de compilação da aplicação. Também é necessário digitar no shell o seguinte comando antes de rodar a aplicação:

ulimit -c unlimited

O comando configura o tamanho do core dump gerado. Como queria o maior possível para detectar a falha, utilizei o argumento “unlimited”. Rode o programa… Espere pelo crash… E pronto! Agora você terá um ‘snapshot’ no ponto exato que ocorreu a falha. Para verificar seu ‘snapshot’ use o comando:

gdb program core

Você terá esses dados para depurar. Em um artigo anterior, dei umas dicas de como usar o gdb (que é muito simples). Se sentirem interesse, poderei fazer um artigo mostrando o poder do gdb.

Obrigado e até!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.