Técnicas de Depuração
Ferramentas de Detecção de Vazamentos de Memória
1. Valgrind: Análise Completa de Memória
graph TD
A[Execução do Programa] --> B[Análise do Valgrind]
B --> C{Vazamento de Memória Detetado?}
C -->|Sim| D[Relatório Detalhado]
C -->|Não| E[Uso de Memória Limpo]
Exemplo de Uso do Valgrind
## Compilar com símbolos de depuração
gcc -g memory_program.c -o memory_program
## Executar o Valgrind
valgrind --leak-check=full ./memory_program
2. AddressSanitizer (ASan)
| Característica |
Descrição |
| Detecção em Tempo de Execução |
Identificação imediata de erros de memória |
| Instrumentação em Tempo de Compilação |
Adiciona código de verificação de memória |
| Baixa Sobrecarga |
Impacto mínimo no desempenho |
Compilação com ASan
gcc -fsanitize=address -g memory_program.c -o memory_program
Técnicas de Depuração
Padrões de Rastreio de Memória
#define TRACK_MEMORY 1
#if TRACK_MEMORY
typedef struct {
void *ptr;
size_t size;
const char *file;
int line;
} MemoryRecord;
MemoryRecord memory_log[1000];
int memory_log_count = 0;
void* safe_malloc(size_t size, const char *file, int line) {
void *ptr = malloc(size);
if (ptr) {
memory_log[memory_log_count].ptr = ptr;
memory_log[memory_log_count].size = size;
memory_log[memory_log_count].file = file;
memory_log[memory_log_count].line = line;
memory_log_count++;
}
return ptr;
}
#define malloc(size) safe_malloc(size, __FILE__, __LINE__)
#endif
Estratégias Avançadas de Depuração
graph LR
A[Depuração de Memória] --> B[Análise Estática]
A --> C[Análise Dinâmica]
A --> D[Verificação em Tempo de Execução]
B --> E[Revisão de Código]
C --> F[Perfilamento de Memória]
D --> G[Instrumentação]
Lista de Verificação de Depuração de Memória
- Usar flags de compilação de depuração
- Implementar tratamento abrangente de erros
- Utilizar mecanismos de rastreio de memória
- Realizar revisões regulares de código
Abordagem Recomendada pela LabEx
Depuração Sistemática de Memória
void debug_memory_allocation() {
// Alocação com verificação explícita de erros
int *data = malloc(sizeof(int) * 100);
if (data == NULL) {
fprintf(stderr, "Crítico: Falha na alocação de memória\n");
// Implementar tratamento de erros apropriado
exit(EXIT_FAILURE);
}
// Uso da memória
// Desalocação explícita
free(data);
}
Comparação de Ferramentas
| Ferramenta |
Pontos Fortes |
Limitações |
| Valgrind |
Detecção abrangente de vazamentos |
Sobrecarga de desempenho |
| ASan |
Detecção de erros em tempo real |
Requer recompilação |
| Purify |
Solução comercial |
Custo proibitivo |
Princípios Chave de Depuração
- Implementar programação defensiva
- Utilizar ferramentas de análise estática e dinâmica
- Criar casos de teste reproduzíveis
- Registrar e rastrear alocações de memória
- Realizar auditorias regulares de código
Dicas Práticas de Depuração
- Compilar com a flag
-g para obter informações de símbolos
- Usar
#ifdef DEBUG para código de depuração condicional
- Implementar rastreio de memória personalizado
- Utilizar análise de dump de núcleo
- Praticar depuração incremental