Zig Crash em Runtime — Identificar e Corrigir
Crashes em runtime no Zig são geralmente detectáveis e fornecem informações detalhadas em modo Debug. Este guia ajuda a identificar as causas mais comuns e como corrigi-las.
Tipos de Crashes
1. Panic: “index out of bounds”
Causa: Acessar um índice fora dos limites de um array ou slice.
const arr = [_]i32{ 1, 2, 3 };
// const x = arr[5]; // PANIC: index out of bounds
// SOLUÇÃO: Verificar limites
if (indice < arr.len) {
const x = arr[indice];
_ = x;
}
2. Panic: “reached unreachable code”
Causa: Execução atingiu um ponto marcado como unreachable.
const valor: u8 = switch (x) {
0 => "zero",
1 => "um",
else => unreachable, // PANIC se x não for 0 ou 1
};
// SOLUÇÃO: Tratar todos os casos ou usar else
const valor: u8 = switch (x) {
0 => "zero",
1 => "um",
else => "outro",
};
3. Panic: “integer overflow”
Causa: Operação aritmética excede o range (apenas em Debug mode).
var x: u8 = 255;
// x += 1; // PANIC: integer overflow
// SOLUÇÃO 1: Usar tipo maior
var x: u16 = 255;
x += 1; // OK: 256
// SOLUÇÃO 2: Wrapping
var y: u8 = 255;
y +%= 1; // 0, sem panic
// SOLUÇÃO 3: Verificar antes
if (x < 255) x += 1;
4. Panic: “attempt to unwrap null”
Causa: Usar .? em um optional que é null.
const maybe: ?i32 = null;
// const x = maybe.?; // PANIC!
// SOLUÇÃO: Verificar antes
const x = maybe orelse {
std.debug.print("Valor era null!\n", .{});
return;
};
5. Stack Overflow
Causa: Recursão muito profunda ou alocação grande na stack.
// PROBLEMA: Recursão infinita
fn recursiva(n: usize) usize {
return recursiva(n + 1); // stack overflow
}
// SOLUÇÃO: Caso base
fn recursiva(n: usize) usize {
if (n >= 1000) return n;
return recursiva(n + 1);
}
// PROBLEMA: Array grande na stack
// var buffer: [100_000_000]u8 = undefined; // stack overflow!
// SOLUÇÃO: Alocar no heap
const buffer = try allocator.alloc(u8, 100_000_000);
defer allocator.free(buffer);
Como Depurar
1. Compilar em modo Debug
# Modo debug (padrão) — máxima informação
zig build
# NUNCA depurar com ReleaseFast — remove verificações
# zig build -Doptimize=ReleaseFast # NÃO para debug
2. Ler o Stack Trace
thread 12345 panic: index out of bounds
src/main.zig:42:15: 0x204a3b in processar (main)
const valor = dados[indice];
^
src/main.zig:28:5: 0x204912 in main (main)
try processar(meus_dados);
^
- Linha 1: Tipo do panic
- Linha 2-3: Arquivo, linha e coluna exatos
- Linha 4-5: Quem chamou a função
3. Usar std.debug.print
fn processar(dados: []const u8, indice: usize) void {
std.debug.print("dados.len={d}, indice={d}\n", .{ dados.len, indice });
// Agora você vê os valores antes do crash
const valor = dados[indice];
_ = valor;
}
4. Usar GDB/LLDB
# Compilar com informações de debug
zig build
# Usar GDB
gdb ./zig-out/bin/meu-app
(gdb) run
(gdb) backtrace # ver stack trace
(gdb) print variavel # inspecionar valores
# Usar LLDB (macOS)
lldb ./zig-out/bin/meu-app
(lldb) run
(lldb) bt # backtrace
Veja Também
- Ler Stack Traces — Interpretar stack traces
- Debugar Segfaults — Resolver segmentation faults
- Memory Leak — Encontrar vazamentos
- Error Handling — Prevenir crashes com tratamento de erros
- FAQ Iniciantes — Perguntas comuns sobre erros