Как собрать Rust проект в release режиме с отладочной информацией (debug symbols)?
Решение: Настройка профиля release в Cargo.toml
Да, вы правы — стандартный release профиль в Cargo вырезает всю отладочную информацию (флаг strip = true по умолчанию). Это делается для минимизации размера бинарного файла. Однако Rust позволяет тонко настроить поведение сборки через секцию [profile.release] в файле Cargo.toml.
Чтобы получить release сборку с сохранением debug-символов, нужно явно указать debug = true или debug = 1 (второе — минимальный уровень для backtrace). Также стоит обратить внимание на флаг strip, который по умолчанию вырезает символы. Вот правильная конфигурация:
# Cargo.toml
[package]
name = "my_app"
version = "0.1.0"
[profile.release]
# Включаем отладочную информацию (уровень 2 — полная)
debug = true
# Отключаем автоматическое вырезание символов
strip = false
# Оптимизация остаётся на максимуме (по умолчанию 3)
opt-level = 3
После этого выполните cargo build --release. Теперь при падении программы с RUST_BACKTRACE=1 вы увидите читаемые имена функций, номера строк и даже сможете использовать внешние инструменты вроде gdb или lldb для отладки release-сборки.
Детальное объяснение параметров
-
debug = true(эквивалентdebug = 2) — сохраняет полную DWARF-информацию: типы, переменные, номера строк. Размер бинарника вырастет в 2-3 раза, но это необходимо для детального бектрейса. -
debug = 1— минимальный уровень: только номера строк и имена функций. Этого достаточно для backtrace, но не для пошаговой отладки. -
strip = false— запрещает Cargo удалять символы. По умолчанию в release стоитstrip = "symbols", что делает backtrace бесполезным.
Пример до и после
До настройки (release по умолчанию):
$ RUST_BACKTRACE=1 cargo run --release
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value', src/main.rs:5
stack backtrace:
0: 0x55a2b3c4d5e6 - <unknown>
1: 0x55a2b3c4d5e7 - <unknown>
...
После настройки профиля:
$ RUST_BACKTRACE=1 cargo run --release
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value', src/main.rs:5
stack backtrace:
0: std::panicking::begin_panic
1: core::result::unwrap_failed
2: my_app::main
...
Важные замечания
- Не забудьте добавить
RUST_BACKTRACE=1в переменные окружения. В Windows можно использовать командуset RUST_BACKTRACE=1 && cargo run --release. - Если вы используете сторонние крейты (например,
anyhowилиcolor-eyre), убедитесь, что они тоже собраны с debug-символами. Для этого можно добавитьdebug = trueв[profile.release.package.*]или глобально. - Для продакшена обычно используют
debug = 1иstrip = "debuginfo"— это компромисс между размером и возможностью отладки.
Теперь вы можете отлаживать release сборки, не жертвуя производительностью!
<<Альтернативный подход: раздельные профили для отладки и продакшена
Иногда не хочется менять глобальный профиль release, особенно если вы собираете бинарник для распространения. В таком случае можно создать отдельный профиль, например release-with-debug, и использовать его по необходимости.
# Cargo.toml
[profile.release-with-debug]
inherits = "release" # наследуем все настройки из release
debug = true
strip = false
Теперь сборка выполняется командой:
cargo build --profile release-with-debug
Обратите внимание: в команде используется --profile, а не --release. Бинарник появится в папке target/release-with-debug/.
Использование переменной окружения CARGO_PROFILE
Если вам нужно быстро переключиться без правки файла, можно задать параметры через переменные окружения:
CARGO_PROFILE_RELEASE_DEBUG=true CARGO_PROFILE_RELEASE_STRIP=false cargo build --release
Это не требует изменения Cargo.toml и подходит для одноразовых отладочных сессий.
Минусы подхода
- Придётся помнить, какой профиль используется для текущей сборки.
- Размер бинарника будет больше, чем у обычного release.
- В CI/CD системах нужно явно указывать профиль, иначе символы не попадут в артефакты.
Выбирайте тот способ, который удобнее для вашего рабочего процесса. Главное — не забывайте, что для окончательной поставки пользователям лучше использовать стандартный release профиль без отладочной информации.