Depuração de código Rust: guia completo sobre técnicas e ferramentas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Depuração de código Rust: do «println!» às ferramentas profissionais



Todo mundo que escreveu em Rust por pelo menos uma semana conhece essa sensação: o compilador aprovou, o programa compilou, é executado… e faz algo completamente inesperado. Ou simplesmente trava com um misterioso Segmentation fault. Bem-vindo ao mundo da depuração! A boa notícia: em Rust, há todo um arsenal para isso — desde uma macro simples até depuradores avançados. Neste artigo, vamos abordar todas as formas de depuração de código Rust, das básicas às profissionais.



1. Kit básico: macros dbg! e eprintln!



Vamos começar com o mais simples e acessível. Se você está escrevendo código Rust e quer entender rapidamente o que está acontecendo nas variáveis — use dbg!. Ele exibe o nome da variável, seu valor, e o arquivo com a linha. Muito mais prático que o velho println!.



fn calculate_even_sum(numbers: &[i32]) -> i32 {    let mut sum = 0;    for &n in numbers {        if n % 2 == 0 {            sum += n;            dbg!(n, sum);  // vemos cada número par e a soma atual        }    }    sum}

fn main() { let data = vec![1, 2, 3, 4, 5, 6]; let result = calculate_even_sum(&data); dbg!(result);}


Execute — e verá algo como:



[src/main.rs:6:13] n = 2[src/main.rs:6:13] sum = 2[src/main.rs:6:13] n = 4[src/main.rs:6:13] sum = 6[src/main.rs:6:13] n = 6[src/main.rs:6:13] sum = 12[src/main.rs:12:5] result = 12


E se precisar escrever no stderr (por exemplo, para não interferir no stdout durante pipes) — use eprintln!. Isso é indispensável na depuração de código Rust em ambiente de produção.



2. Logging avançado com log e env_logger



Quando o projeto cresce, espalhar dbg! por todo o código se torna doloroso. As crates log e env_logger vêm em socorro. Elas permitem ativar/desativar logs sem recompilação.



use log::{info, warn, error, debug};

fn main() { env_logger::init();

info!("Programa iniciado"); let x = 42; debug!("Valor de x: {}", x);

if x > 100 { warn!("x é muito grande!"); } else { error!("Isso não é um erro, apenas uma verificação"); }}


Execute com a variável de ambiente RUST_LOG=debug cargo run — e obterá todos os logs. Quer apenas avisos? RUST_LOG=warn. Muito útil para depuração de aplicações Rust em tempo real.



3. Pânico e backtrace: lendo a pilha de erros



Quando o programa entra em pânico, o Rust exibe uma mensagem. Mas muitas vezes isso não é suficiente. Ative o backtrace completo:



$ RUST_BACKTRACE=1 cargo run


Ou para máxima detalhamento:



$ RUST_BACKTRACE=full cargo run


Você verá toda a pilha de chamadas — do ponto da falha até o main. Isso é criticamente importante na depuração de código Rust se você não entender de onde veio o erro.



Exemplo: suponha que você tenha este código:



fn main() {    let v = vec![1, 2, 3];    println!("{}", v[10]);  // pânico!}


Com RUST_BACKTRACE=1, você verá não apenas "index out of bounds", mas a linha exata e a chamada.



4. Modo de depuração e otimização: debug vs release



Um ponto importante: a depuração de código Rust no modo debug (padrão) fornece informações completas. Mas no modo release, o compilador otimiza o código, e algumas variáveis podem desaparecer ou ter a ordem alterada. Se você está depurando um bug de "release" — use um perfil com informações de depuração:



[profile.release]debug = true


No Cargo.toml. Isso permitirá executar cargo run --release

Blogs

Book Recommendations