CodeSampleX

샘플

anyhow 1.0.104: RUST_LIB_BACKTRACE overrides RUST_BACKTRACE during eager anyhow backtrace capture, and Debug formatting appends stack traces only when Captured

검증된 샘플 — cargo anyhow 1.0.104: RUST_LIB_BACKTRACE overrides RUST_BACKTRACE during eager anyhow backtrace capture, and Debug formatting appends stack traces…

sha256:0d060c885ab1406bc8e8bff006df2cbc2e81b0c74808b71073845ec073c38003

이 네트워크가 제공하는 것은 하나입니다. 빌드되는 샘플. 샌드박스에서 돌리고 서명된 영수증을 보관합니다. 등급을 매기지 않고 무엇도 보증하지 않습니다 — 같은 코드가 당신 환경에서 빌드되는지는 측정한 적이 없습니다. 통과한 계약 영수증을 낸 서로 다른 서명 키의 수입니다. 하나면 작성자 혼자이고, 둘 이상이면 다른 사람도 빌드했다는 뜻입니다. 키는 스스로 만드는 것이고 뒤에 등록된 신원이 없으므로, 세는 것은 사람이 아니라 키입니다. MIT-0

실행 증거

선언된 환경과 서명된 실행을 분리해 두었습니다. 이 샘플이 무엇을 어디서 실행했는지 그대로 볼 수 있습니다.

증거 기준
서명된 컨트랙트 통과
검증 영수증
2
빌드한 서명 키
2
선언된 환경 rust linux x64 rust rust cargo

검증 실행 환경

환경 컨트랙트 단계 실행일
rust 1 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · cargo@1
2026-08-16
rust 1 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · cargo@1
2026-08-18

케이스

HOW
목표
RUST_LIB_BACKTRACE overrides RUST_BACKTRACE during eager anyhow backtrace capture, and Debug formatting appends stack traces only when Captured
패키지
심벌
  • anyhow::Error::backtrace
  • std::backtrace::Backtrace::status
  • std::backtrace::BacktraceStatus
  • anyhow::bail
  • anyhow::Context::context
환경
rust
생성일
2026-08-16T07:54:49Z

컨트랙트

  1. assert anyhow captures backtraces with status Captured when RUST_BACKTRACE is enabled
  2. assert anyhow backtrace status is Disabled when RUST_BACKTRACE is zero or unset
  3. assert RUST_LIB_BACKTRACE=0 overrides RUST_BACKTRACE=1 to disable anyhow backtrace capture
  4. assert RUST_LIB_BACKTRACE=1 overrides RUST_BACKTRACE=0 to enable anyhow backtrace capture
  5. assert anyhow backtrace capture is eager at instantiation time and does not capture retroactively when env changes
  6. assert Debug formatting appends Stack backtrace only when backtrace status is Captured
  7. assert Display and Alternate Display format error messages and chains without backtrace frames
  8. assert anyhow::Error::backtrace provides an inherent method returning a reference to std Backtrace

파일

  • Cargo.lock
  • Cargo.toml
  • NOTES.md
  • csx.json
  • src/bin/inspector.rs
  • src/lib.rs
  • tests/contract.rs

소스 아티팩트 내려받기 (tar.gz)

소스

Cargo.lock
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4

[[package]]
name = "anyhow"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"

[[package]]
name = "cargo-anyhow-config"
version = "0.1.0"
dependencies = [
 "anyhow",
]
Cargo.toml
[package]
name = "cargo-anyhow-config"
version = "0.1.0"
edition = "2021"
license = "MIT-0"

[dependencies]
anyhow = "1.0.104"
NOTES.md
# CSX Sample Notes: `anyhow` Backtrace Capture Timing and `RUST_BACKTRACE` vs `RUST_LIB_BACKTRACE` Precedence

## Search Known Solution Result
- `search_known_solution` returned a published sample:
  - `sha256:709971847660bb4f230ee832aa66da4263481bd8d5e0a498178ee3b789c53404` (*"Handle errors in a Rust application with anyhow: attach context, keep the cause chain, log it without losing the cause, and recover the concrete error"*).
- **Why this sample is distinct**: That existing sample focuses on standard application error handling, context layering (`.context()` / `.with_context()`), source chain iteration (`.chain()`), and type downcasting (`.downcast_ref()`). In contrast, this sample targets the environment variable and configuration traps governing `anyhow::Error::backtrace()`:
  1. `anyhow` captures the backtrace eagerly at error construction time (e.g. at `bail!`, `anyhow!`, or `.context()`), NOT lazily when the error is formatted or logged.
  2. `RUST_LIB_BACKTRACE` has strict precedence over `RUST_BACKTRACE`: `RUST_LIB_BACKTRACE=0` suppresses backtrace capture even when `RUST_BACKTRACE=1` is set, while `RUST_LIB_BACKTRACE=1` forces capture even when `RUST_BACKTRACE=0`.
  3. `{:?}` (Debug) appends `Stack backtrace:` if and only if the backtrace status is `Captured`, while `{}` (Display) and `{:#}` (Alternate Display) always omit backtraces regardless of environment variable settings.

## What a Model Would Have Written Instead
A model would assume that `anyhow::Error::backtrace()` evaluates the backtrace on-demand at print/inspection time, that `RUST_BACKTRACE=1` dynamically populates stack traces for errors created prior to the variable being set, and that `RUST_BACKTRACE` overrides `RUST_LIB_BACKTRACE`.

## How the Wrong Version Fails
Silently with a green build: the code compiles and runs cleanly, but production diagnostic logs and `err.backtrace()` return empty/disabled traces (`BacktraceStatus::Disabled`) whenever `RUST_LIB_BACKTRACE=0` is set in base containers or when errors are instantiated before dynamic runtime configuration.
csx.json
{"case":{"caseId":"case:sha256:9caee5c167d18db1cb05ada462ae92bd79d87888bfdf18534bad16f588ad23dd","contract":["assert anyhow captures backtraces with status Captured when RUST_BACKTRACE is enabled","assert anyhow backtrace status is Disabled when RUST_BACKTRACE is zero or unset","assert RUST_LIB_BACKTRACE=0 overrides RUST_BACKTRACE=1 to disable anyhow backtrace capture","assert RUST_LIB_BACKTRACE=1 overrides RUST_BACKTRACE=0 to enable anyhow backtrace capture","assert anyhow backtrace capture is eager at instantiation time and does not capture retroactively when env changes","assert Debug formatting appends Stack backtrace only when backtrace status is Captured","assert Display and Alternate Display format error messages and chains without backtrace frames","assert anyhow::Error::backtrace provides an inherent method returning a reference to std Backtrace"],"goal":"RUST_LIB_BACKTRACE overrides RUST_BACKTRACE during eager anyhow backtrace capture, and Debug formatting appends stack traces only when Captured","kind":"HOW","packages":["pkg:cargo/anyhow@1.0.104"],"schemaVersion":1,"symbols":["anyhow::Error::backtrace","std::backtrace::Backtrace::status","std::backtrace::BacktraceStatus","anyhow::bail","anyhow::Context::context"]},"contractCommand":["cargo","test","--offline"],"environment":{"arch":"x64","ecosystem":"cargo","executionContext":"rust","language":"rust","os":"linux","packageManager":"cargo","runtime":"rust","schemaVersion":1},"license":"MIT-0","packages":["pkg:cargo/anyhow@1.0.104"],"schemaVersion":1,"symbols":["anyhow::Error::backtrace","std::backtrace::Backtrace::status","std::backtrace::BacktraceStatus","anyhow::bail","anyhow::Context::context"],"verifierAdapter":"cargo@1"}
src/bin/inspector.rs
use anyhow::{bail, Context, Result};

fn inner_op() -> Result<()> {
    bail!("low-level storage disk failure")
}

fn middle_op() -> Result<()> {
    inner_op().context("processing chunk payload")
}

fn main() {
    let mode = std::env::args().nth(1).unwrap_or_default();

    match mode.as_str() {
        "--status" => {
            let err = middle_op().unwrap_err();
            println!("STATUS:{:?}", err.backtrace().status());
        }
        "--debug" => {
            let err = middle_op().unwrap_err();
            println!("DEBUG:\n{:?}", err);
        }
        "--display" => {
            let err = middle_op().unwrap_err();
            println!("DISPLAY:\n{}", err);
        }
        "--alt-display" => {
            let err = middle_op().unwrap_err();
            println!("ALT_DISPLAY:\n{:#}", err);
        }
        "--eager-trap" => {
            // Error created under initial env
            let err = middle_op().unwrap_err();
            // Env changed after error creation
            std::env::set_var("RUST_BACKTRACE", "1");
            println!("EAGER_STATUS:{:?}", err.backtrace().status());
            println!("EAGER_DEBUG:\n{:?}", err);
        }
        _ => {
            let err = middle_op().unwrap_err();
            println!("STATUS:{:?}", err.backtrace().status());
            println!("DEBUG:\n{:?}", err);
        }
    }
}
src/lib.rs
use anyhow::{anyhow, Context, Result};
use std::backtrace::Backtrace;

/// Creates an error with a contextual message layer.
pub fn fail_with_context(detail: &str) -> Result<()> {
    let err = anyhow!("underlying io failure: {detail}");
    Err(err).context("executing storage transaction")
}

/// Inspects the attached backtrace from an anyhow error.
pub fn inspect_backtrace(err: &anyhow::Error) -> &Backtrace {
    err.backtrace()
}
tests/contract.rs
use cargo_anyhow_config::{fail_with_context, inspect_backtrace};
use std::backtrace::{Backtrace, BacktraceStatus};
use std::process::Command;

const INSPECTOR_BIN: &str = env!("CARGO_BIN_EXE_inspector");

#[test]
fn test_backtrace_captured_when_rust_backtrace_enabled() {
    let output = Command::new(INSPECTOR_BIN)
        .arg("--status")
        .env("RUST_BACKTRACE", "1")
        .env_remove("RUST_LIB_BACKTRACE")
        .output()
        .expect("failed to run inspector");

    assert!(output.status.success());
    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(
        stdout.contains("STATUS:Captured"),
        "Expected STATUS:Captured when RUST_BACKTRACE=1, got: {stdout}"
    );
}

#[test]
fn test_backtrace_disabled_when_rust_backtrace_zero_or_unset() {
    let output = Command::new(INSPECTOR_BIN)
        .arg("--status")
        .env("RUST_BACKTRACE", "0")
        .env_remove("RUST_LIB_BACKTRACE")
        .output()
        .expect("failed to run inspector");

    assert!(output.status.success());
    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(
        stdout.contains("STATUS:Disabled"),
        "Expected STATUS:Disabled when RUST_BACKTRACE=0, got: {stdout}"
    );
}

#[test]
fn test_rust_lib_backtrace_overrides_rust_backtrace() {
    // When RUST_BACKTRACE=1 but RUST_LIB_BACKTRACE=0, backtrace is disabled
    let output_override_disable = Command::new(INSPECTOR_BIN)
        .arg("--status")
        .env("RUST_BACKTRACE", "1")
        .env("RUST_LIB_BACKTRACE", "0")
        .output()
        .expect("failed to run inspector");

    assert!(output_override_disable.status.success());
    let stdout_dis = String::from_utf8_lossy(&output_override_disable.stdout);
    assert!(
        stdout_dis.contains("STATUS:Disabled"),
        "RUST_LIB_BACKTRACE=0 must override RUST_BACKTRACE=1, got: {stdout_dis}"
    );

    // When RUST_BACKTRACE=0 but RUST_LIB_BACKTRACE=1, backtrace is enabled
    let output_override_enable = Command::new(INSPECTOR_BIN)
        .arg("--status")
        .env("RUST_BACKTRACE", "0")
        .env("RUST_LIB_BACKTRACE", "1")
        .output()
        .expect("failed to run inspector");

    assert!(output_override_enable.status.success());
    let stdout_en = String::from_utf8_lossy(&output_override_enable.stdout);
    assert!(
        stdout_en.contains("STATUS:Captured"),
        "RUST_LIB_BACKTRACE=1 must override RUST_BACKTRACE=0, got: {stdout_en}"
    );
}

#[test]
fn test_eager_backtrace_capture_at_instantiation_time() {
    // When error is instantiated with RUST_BACKTRACE=0, setting it to 1 later does not capture backtrace
    let output = Command::new(INSPECTOR_BIN)
        .arg("--eager-trap")
        .env("RUST_BACKTRACE", "0")
        .env_remove("RUST_LIB_BACKTRACE")
        .output()
        .expect("failed to run inspector");

    assert!(output.status.success());
    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(
        stdout.contains("EAGER_STATUS:Disabled"),
        "Eager capture at error construction time must remain Disabled even if env changed later, got: {stdout}"
    );
    assert!(
        !stdout.contains("Stack backtrace:"),
        "Debug output must not contain Stack backtrace when created with backtrace disabled"
    );
}

#[test]
fn test_debug_formatting_appends_stack_trace_only_when_captured() {
    // With RUST_BACKTRACE=1: Debug output includes "Stack backtrace:"
    let output_enabled = Command::new(INSPECTOR_BIN)
        .arg("--debug")
        .env("RUST_BACKTRACE", "1")
        .env_remove("RUST_LIB_BACKTRACE")
        .output()
        .expect("failed to run inspector");

    assert!(output_enabled.status.success());
    let stdout_en = String::from_utf8_lossy(&output_enabled.stdout);
    assert!(
        stdout_en.contains("processing chunk payload"),
        "Debug output must contain context frame"
    );
    assert!(
        stdout_en.contains("Caused by:"),
        "Debug output must contain cause chain"
    );
    assert!(
        stdout_en.contains("Stack backtrace:"),
        "Debug output must contain Stack backtrace when RUST_BACKTRACE=1, got: {stdout_en}"
    );

    // With RUST_BACKTRACE=0: Debug output does NOT contain "Stack backtrace:"
    let output_disabled = Command::new(INSPECTOR_BIN)
        .arg("--debug")
        .env("RUST_BACKTRACE", "0")
        .env_remove("RUST_LIB_BACKTRACE")
        .output()
        .expect("failed to run inspector");

    assert!(output_disabled.status.success());
    let stdout_dis = String::from_utf8_lossy(&output_disabled.stdout);
    assert!(
        stdout_dis.contains("processing chunk payload"),
        "Debug output must contain context frame"
    );
    assert!(
        stdout_dis.contains("Caused by:"),
        "Debug output must contain cause chain"
    );
    assert!(
        !stdout_dis.contains("Stack backtrace:"),
        "Debug output must NOT contain Stack backtrace when RUST_BACKTRACE=0, got: {stdout_dis}"
    );
}

#[test]
fn test_display_formats_remain_clean_across_backtrace_settings() {
    // Display format {} prints only outermost frame regardless of backtrace env
    let output_display = Command::new(INSPECTOR_BIN)
        .arg("--display")
        .env("RUST_BACKTRACE", "1")
        .output()
        .expect("failed to run inspector");

    let stdout_disp = String::from_utf8_lossy(&output_display.stdout);
    assert!(
        stdout_disp.contains("DISPLAY:\nprocessing chunk payload"),
        "Display format prints only outermost context frame"
    );
    assert!(
        !stdout_disp.contains("Stack backtrace:"),
        "Display format never appends backtrace"
    );

    // Alternate Display {:#} flattens cause chain with colon separator without backtrace
    let output_alt = Command::new(INSPECTOR_BIN)
        .arg("--alt-display")
        .env("RUST_BACKTRACE", "1")
        .output()
        .expect("failed to run inspector");

    let stdout_alt = String::from_utf8_lossy(&output_alt.stdout);
    assert!(
        stdout_alt.contains("ALT_DISPLAY:\nprocessing chunk payload: low-level storage disk failure"),
        "Alternate display joins error chain with colon"
    );
    assert!(
        !stdout_alt.contains("Stack backtrace:"),
        "Alternate display never appends backtrace"
    );
}

#[test]
fn test_anyhow_error_inherent_backtrace_method() {
    let err = fail_with_context("disk sector bad").unwrap_err();
    let bt: &Backtrace = inspect_backtrace(&err);
    // Backtrace is an inherent method on anyhow::Error, returning a valid reference
    match bt.status() {
        BacktraceStatus::Captured | BacktraceStatus::Disabled | BacktraceStatus::Unsupported => {}
        _ => panic!("Unknown backtrace status"),
    }
}

오리진 시더

csx-seed