summaryrefslogtreecommitdiffstats
path: root/library/std/src/backtrace/tests.rs
blob: 73543a3af548f47e5e73f9af385be4a40694972b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use super::*;
use crate::panic::{RefUnwindSafe, UnwindSafe};

fn generate_fake_frames() -> Vec<BacktraceFrame> {
    vec![
        BacktraceFrame {
            frame: RawFrame::Fake,
            symbols: vec![BacktraceSymbol {
                name: Some(b"std::backtrace::Backtrace::create".to_vec()),
                filename: Some(BytesOrWide::Bytes(b"rust/backtrace.rs".to_vec())),
                lineno: Some(100),
                colno: None,
            }],
        },
        BacktraceFrame {
            frame: RawFrame::Fake,
            symbols: vec![BacktraceSymbol {
                name: Some(b"__rust_maybe_catch_panic".to_vec()),
                filename: None,
                lineno: None,
                colno: None,
            }],
        },
        BacktraceFrame {
            frame: RawFrame::Fake,
            symbols: vec![
                BacktraceSymbol {
                    name: Some(b"std::rt::lang_start_internal".to_vec()),
                    filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())),
                    lineno: Some(300),
                    colno: Some(5),
                },
                BacktraceSymbol {
                    name: Some(b"std::rt::lang_start".to_vec()),
                    filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())),
                    lineno: Some(400),
                    colno: None,
                },
            ],
        },
    ]
}

#[test]
fn test_debug() {
    let backtrace = Backtrace {
        inner: Inner::Captured(LazyLock::preinit(Capture {
            actual_start: 1,
            frames: generate_fake_frames(),
        })),
    };

    #[rustfmt::skip]
    let expected = "Backtrace [\
    \n    { fn: \"__rust_maybe_catch_panic\" },\
    \n    { fn: \"std::rt::lang_start_internal\", file: \"rust/rt.rs\", line: 300 },\
    \n    { fn: \"std::rt::lang_start\", file: \"rust/rt.rs\", line: 400 },\
    \n]";

    assert_eq!(format!("{backtrace:#?}"), expected);

    // Format the backtrace a second time, just to make sure lazily resolved state is stable
    assert_eq!(format!("{backtrace:#?}"), expected);
}

#[test]
fn test_frames() {
    let backtrace = Backtrace {
        inner: Inner::Captured(LazyLock::preinit(Capture {
            actual_start: 1,
            frames: generate_fake_frames(),
        })),
    };

    let frames = backtrace.frames();

    #[rustfmt::skip]
    let expected = vec![
        "[
    { fn: \"std::backtrace::Backtrace::create\", file: \"rust/backtrace.rs\", line: 100 },
]",
        "[
    { fn: \"__rust_maybe_catch_panic\" },
]",
        "[
    { fn: \"std::rt::lang_start_internal\", file: \"rust/rt.rs\", line: 300 },
    { fn: \"std::rt::lang_start\", file: \"rust/rt.rs\", line: 400 },
]"
    ];

    let mut iter = frames.iter().zip(expected.iter());

    assert!(iter.all(|(f, e)| format!("{f:#?}") == *e));
}

#[test]
fn backtrace_unwind_safe() {
    fn assert_unwind_safe<T: UnwindSafe + RefUnwindSafe>() {}
    assert_unwind_safe::<Backtrace>();
}