---
title: "Debugar Segfaults em Zig — Resolver Segmentation Faults"
url: "https://ziglang.com.br/troubleshooting/debugar-segfaults-em-zig-resolver-segmentation-faults/"
markdown_url: "https://ziglang.com.br/troubleshooting/debugar-segfaults-em-zig-resolver-segmentation-faults.MD"
description: "Guia para debugar segmentation faults em Zig. Use-after-free, null pointer, buffer overflow, stack overflow, alignment e ferramentas de debug como GDB e sanitizers."
date: "2026-02-21"
author: "Zig Brasil"
---

# Debugar Segfaults em Zig — Resolver Segmentation Faults

Guia para debugar segmentation faults em Zig. Use-after-free, null pointer, buffer overflow, stack overflow, alignment e ferramentas de debug como GDB e sanitizers.


# Debugar Segfaults em Zig — Resolver Segmentation Faults

Segmentation faults (segfaults) ocorrem quando o programa tenta acessar memória inválida. Em Zig, o modo Debug detecta muitas dessas situações antes que se tornem segfaults, mas algumas podem escapar. Este guia ajuda a diagnosticar e corrigir.

## Causas Comuns de Segfault

### 1. Use-After-Free

Acessar memória que já foi liberada:

```zig
// PERIGO: use-after-free
fn exemplo(allocator: std.mem.Allocator) !void {
    const dados = try allocator.alloc(u8, 100);
    allocator.free(dados);
    // dados[0] = 42; // SEGFAULT! Memória já liberada

    // CORRETO: não acessar após free
    const dados2 = try allocator.alloc(u8, 100);
    defer allocator.free(dados2); // free acontece ao sair do escopo
    dados2[0] = 42; // OK
}
```

**Detecção:** Use `GeneralPurposeAllocator` em Debug — ele preenche memória liberada com um padrão especial e detecta use-after-free.

### 2. Dangling Pointer (Ponteiro para Stack)

Retornar ponteiro para variável local:

```zig
// PERIGO: ponteiro para stack que já não existe
fn perigoso() *i32 {
    var x: i32 = 42;
    return &x; // SEGFAULT quando usado! x já morreu
}

// CORRETO: alocar no heap
fn correto(allocator: std.mem.Allocator) !*i32 {
    const ptr = try allocator.create(i32);
    ptr.* = 42;
    return ptr; // OK — vive no heap até ser liberado
}
```

### 3. Null Pointer Dereference

```zig
// Em interop com C, ponteiros podem ser null
const c = @cImport(@cInclude("lib.h"));

const ptr: ?*c.struct_data = c.get_data();
// ptr.*.campo; // SEGFAULT se ptr for null!

// CORRETO: verificar antes
if (ptr) |p| {
    const valor = p.*.campo;
    _ = valor;
} else {
    std.debug.print("Ponteiro null retornado\n", .{});
}
```

### 4. Buffer Overflow

```zig
// PERIGO: escrever além do buffer
var buffer: [10]u8 = undefined;
// Em Debug mode, Zig detecta e dá panic
// Em Release, pode causar segfault ou corrupção silenciosa

// CORRETO: verificar limites
if (indice < buffer.len) {
    buffer[indice] = valor;
}
```

### 5. Alignment Incorreto

```zig
// PERIGO: cast para tipo com alignment diferente
fn perigoso(bytes: [*]u8) *u32 {
    // Se bytes não está alinhado a 4 bytes:
    return @ptrCast(@alignCast(bytes)); // Pode dar panic ou segfault
}

// CORRETO: verificar alignment
fn correto(bytes: [*]align(1) u8) ?*align(1) const u32 {
    if (@intFromPtr(bytes) % @alignOf(u32) != 0) return null;
    return @ptrCast(bytes);
}
```

## Ferramentas de Debugging

### GDB (Linux)

```bash
# Compilar em Debug
zig build

# Rodar com GDB
gdb ./zig-out/bin/meu-app

# Dentro do GDB:
(gdb) run                    # Executar
(gdb) bt                     # Backtrace quando crashar
(gdb) bt full                # Backtrace com variáveis
(gdb) frame 0                # Ir para frame do crash
(gdb) info registers         # Ver registradores
(gdb) print *ptr             # Inspecionar ponteiro
(gdb) x/10x ptr              # Examinar memória
(gdb) watch *ptr             # Parar quando memória mudar
```

### LLDB (macOS)

```bash
lldb ./zig-out/bin/meu-app
(lldb) run
(lldb) bt
(lldb) frame variable
(lldb) memory read ptr
```

### AddressSanitizer (ASan)

```bash
# Compilar com sanitizer
zig build-exe src/main.zig -fsanitize=address

# Rodar — ASan reporta erros detalhados
./main
# =================================================================
# ==12345==ERROR: AddressSanitizer: heap-use-after-free
#   ...com stack trace detalhado
```

ASan detecta: use-after-free, buffer overflow, stack overflow, memory leaks e double-free.

### Valgrind (Linux)

```bash
zig build
valgrind --tool=memcheck --leak-check=full ./zig-out/bin/meu-app
```

## Debugging Passo a Passo

### 1. Reproduzir o Segfault

```bash
# Compilar em Debug
zig build

# Verificar se o crash é reproduzível
./zig-out/bin/meu-app
```

### 2. Obter o Stack Trace

```bash
# Se o stack trace não aparece, use GDB
gdb -ex run -ex bt -ex quit ./zig-out/bin/meu-app

# Ou habilitar core dumps
ulimit -c unlimited
./zig-out/bin/meu-app
gdb ./zig-out/bin/meu-app core
```

### 3. Localizar o Código Problemático

```zig
// Adicione checkpoints
std.debug.print("Checkpoint 1\n", .{});
// ...código suspeito...
std.debug.print("Checkpoint 2\n", .{});
```

### 4. Isolar com Teste Mínimo

```zig
test "reproduzir segfault" {
    const allocator = std.testing.allocator;
    // Código mínimo que reproduz o problema
    const dados = try allocator.alloc(u8, 10);
    defer allocator.free(dados);
    // ...operação que causa segfault...
}
```

## Segfaults em Interop com C

Interop com C é a causa mais comum de segfaults em Zig:

```zig
const c = @cImport(@cInclude("lib.h"));

// CUIDADO com ponteiros C:
// 1. Sempre verificar null
// 2. Não assumir lifetime
// 3. Não assumir tamanho de buffers

fn usar_lib_c() void {
    const resultado = c.funcao_c();

    // Verificar null
    if (resultado == null) {
        std.debug.print("Erro: retornou null\n", .{});
        return;
    }

    // Verificar tamanho antes de criar slice
    const len = c.get_size(resultado);
    if (len == 0) return;

    // Criar slice seguro
    const slice = resultado.?[0..@intCast(len)];
    _ = slice;
}
```

## Prevenção

1. **Use modo Debug** durante desenvolvimento — detecta a maioria dos problemas
2. **Use `GeneralPurposeAllocator`** — detecta use-after-free e double-free
3. **Sempre verifique ponteiros C** antes de dereferenciar
4. **Use `defer`** para liberar recursos no momento certo
5. **Evite `@ptrCast`** a menos que tenha certeza do alignment e tipo
6. **Rode com ASan** periodicamente para pegar problemas sutis

## Veja Também

- [Crash em Runtime](/troubleshooting/zig-crash-runtime/) — Outros tipos de crashes
- [Ler Stack Traces](/troubleshooting/zig-stack-trace-ler/) — Interpretar stack traces
- [Memory Leak](/troubleshooting/zig-memory-leak-encontrar/) — Detectar vazamentos
- [Linkar Biblioteca C](/troubleshooting/zig-c-library-link/) — Interop com C
- [FAQ Memória](/faq/faq-memoria/) — Gerenciamento de memória
