Отладка Rust кода: полный гайд по техникам и инструментам

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Отладка Rust кода: от «println!» до профи-инструментов

Каждый, кто писал на Rust хотя бы неделю, знает это чувство: компилятор пропустил, программа скомпилировалась, запускается… и делает что-то совершенно неожиданное. Или просто падает с загадочным Segmentation fault. Добро пожаловать в мир отладки! Хорошая новость: в Rust для этого есть целый арсенал — от простого макроса до продвинутых дебаггеров. В этой статье разберём все способы отладки Rust кода, от базовых до профессиональных.

1. Джентльменский набор: макросы dbg! и eprintln!

Начнём с самого простого и доступного. Если вы пишете Rust код и хотите быстро понять, что происходит в переменных — используйте dbg!. Он выводит и имя переменной, и её значение, и файл со строкой. Намного удобнее, чем старый добрый 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);  // смотрим каждое чётное число и текущую сумму
        }
    }
    sum
}

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

Запустите — и увидите что-то вроде:

[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

А если нужно писать в stderr (например, чтобы не мешать stdout при пайпах) — используйте eprintln!. Это незаменимо при отладке Rust кода в продакшн-окружении.

2. Продвинутое логирование с log и env_logger

Когда проект растёт, раскидывать dbg! по всему коду становится больно. На помощь приходят крейты log и env_logger. Они позволяют включать/отключать логи без перекомпиляции.

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

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

    info!("Программа запущена");
    let x = 42;
    debug!("Значение x: {}", x);

    if x > 100 {
        warn!("x слишком большой!");
    } else {
        error!("Это не ошибка, просто проверка");
    }
}

Запускайте с переменной окружения RUST_LOG=debug cargo run — и получите все логи. Хотите только предупреждения? RUST_LOG=warn. Очень удобно для отладки Rust приложений в реальном времени.

3. Паника и backtrace: читаем стек ошибок

Когда программа паникует, Rust выводит сообщение. Но часто этого мало. Включите полный backtrace:

$ RUST_BACKTRACE=1 cargo run

Или для максимальной детализации:

$ RUST_BACKTRACE=full cargo run

Вы увидите весь стек вызовов — от точки падения до main. Это критически важно при отладке Rust кода, если вы не понимаете, откуда взялась ошибка.

Пример: предположим, у вас есть такой код:

fn main() {
    let v = vec![1, 2, 3];
    println!("{}", v[10]);  // паника!
}

С RUST_BACKTRACE=1 вы увидите не просто "index out of bounds", а точную строку и вызов.

4. Режим отладки и оптимизации: debug vs release

Важный момент: отладка Rust кода в режиме debug (по умолчанию) даёт полную информацию. Но в release компилятор оптимизирует код, и некоторые переменные могут исчезнуть или изменить порядок. Если вы отлаживаете «релизный» баг — используйте профиль с отладочной информацией:

[profile.release]
debug = true

В Cargo.toml. Это позволит вам запускать cargo run --release и всё равно видеть нормальные backtrace и переменные в дебаггере.

5. GDB и LLDB: отладка как в старые добрые времена

Если макросов и логов недостаточно (а рано или поздно станет недостаточно), пора переходить к настоящим дебаггерам. Rust отладчик на практике — это GDB (Linux) или LLDB (macOS/Linux). Rust компилируется в нативный код, поэтому работают стандартные инструменты.

Установите точки останова, смотрите переменные, шагайте по строкам:

$ rust-gdb target/debug/my_program
(gdb) break main
(gdb) run
(gdb) next
(gdb) print my_variable
(gdb) continue

Для LLDB команды похожи. Главное — собрать программу с отладочными символами (режим debug по умолчанию). Это мощный инструмент отладки Rust, который даёт полный контроль.

6. VS Code и rust-analyzer: визуальная отладка

Современные IDE делают отладку Rust кода почти как в Python или JavaScript. Установите расширение rust-analyzer и CodeLLDB (или Native Debug для GDB).

Теперь вы можете:

  • Ставить точки останова кликом мыши
  • Смотреть значения переменных в панели
  • Шагать в функции, перешагивать, выходить
  • Смотреть стек вызовов

Это настоящий дебаггер для Rust с графическим интерфейсом. Особенно полезно, если вы привыкли к визуальной отладке в других языках.

7. Анализ паники с human-panic

Для пользовательских приложений (не библиотек) полезен крейт human-panic. Он заменяет стандартное сообщение о панике на более дружелюбное и предлагает отправить отчёт.

use human_panic::setup_panic;

fn main() {
    setup_panic!();
    panic!("Ой, что-то пошло не так");
}

Вместо непонятного текста пользователь увидит что-то вроде: "Похоже, программа столкнулась с проблемой. Хотите помочь разработчикам? Отправьте отчёт." Это не совсем отладка Rust кода для разработчика, но полезно для с

Блоги

Рекомендаций по книгам