首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >__rust_begin_short_backtrace是如何在锈病中工作的?

__rust_begin_short_backtrace是如何在锈病中工作的?
EN

Stack Overflow用户
提问于 2021-05-08 05:17:27
回答 1查看 410关注 0票数 1

标题是。

我知道__rust_begin_short_backtrace用于堆栈回溯,但是它实际上是如何工作的呢?我发现它的实现真的很短,如下所示。它所做的只是间接调用传入函数,并返回结果。我还发现对应函数__rust_end_short_backtrace具有完全相同的实现。代码在library/std/src/sys_common/backtrace.rs.

代码语言:javascript
复制
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
/// this is only inline(never) when backtraces in libstd are enabled, otherwise
/// it's fine to optimize away.
#[cfg_attr(feature = "backtrace", inline(never))]
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
where
    F: FnOnce() -> T,
{
    let result = f();

    // prevent this frame from being tail-call optimised away
    crate::hint::black_box(());

    result
}

相关实现的另一部分也在"library/std/src/sys_common/backtrace.rs".上。下面是这个部分的代码片段,我认为这些代码具有高度的相关性和重要性,但我不理解Rust如何处理与前两个函数相关的符号的逻辑:

代码语言:javascript
复制
 backtrace_rs::trace_unsynchronized(|frame| {
    if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
        return false;
    }

    let mut hit = false;
    let mut stop = false;
    backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
        hit = true;
        if print_fmt == PrintFmt::Short {
            if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
                if sym.contains("__rust_begin_short_backtrace") {
                    stop = true;
                    return;
                }
                if sym.contains("__rust_end_short_backtrace") {
                    start = true;
                    return;
                }
            }
        }

        if start {
            res = bt_fmt.frame().symbol(frame, symbol);
        }
    });
    if stop {
        return false;
    }
    if !hit {
        if start {
            res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
        }
    }

    idx += 1;
    res.is_ok()
});
EN

回答 1

Stack Overflow用户

发布于 2021-05-08 08:51:42

铁锈是插入这些“虚拟符号”,以允许一个简短的回溯。

考虑一下这段代码

代码语言:javascript
复制
fn a() {
    b()
}

fn b() {
    c()
}

fn c() {
    d()
}

fn d() {
    panic!()
}

fn main() {
    a()
}

这给出了一个很好的回溯

代码语言:javascript
复制
$ rustc demo.rs
$ RUST_BACKTRACE=1 ./demo
thread 'main' panicked at 'explicit panic', demo.rs:14:5
stack backtrace:
   0: std::panicking::begin_panic
   1: demo::d
   2: demo::c
   3: demo::b
   4: demo::a
   5: demo::main
   6: core::ops::function::FnOnce::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

如果我们用RUST_BACKTRACE=full

代码语言:javascript
复制
$ RUST_BACKTRACE=full ./demo
thread 'main' panicked at 'explicit panic', demo.rs:14:5
stack backtrace:
   0:        0x107e34fe4 - std::backtrace_rs::backtrace::libunwind::trace::ha70d3c0580051b5e
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
   1:        0x107e34fe4 - std::backtrace_rs::backtrace::trace_unsynchronized::h70c3b3ef22cddd13
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x107e34fe4 - std::sys_common::backtrace::_print_fmt::h698e42c1766250fa
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/sys_common/backtrace.rs:67:5
   3:        0x107e34fe4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h18cc31b07c2f1a67
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/sys_common/backtrace.rs:46:22
   4:        0x107e4808d - core::fmt::write::h24f8349e8e89c9af
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/core/src/fmt/mod.rs:1096:17
   5:        0x107e33046 - std::io::Write::write_fmt::hc54d7d6e95b15753
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/io/mod.rs:1568:15
   6:        0x107e36b79 - std::sys_common::backtrace::_print::h07ca439149358748
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/sys_common/backtrace.rs:49:5
   7:        0x107e36b79 - std::sys_common::backtrace::print::hb7331bf9c4b208ca
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/sys_common/backtrace.rs:36:9
   8:        0x107e36b79 - std::panicking::default_hook::{{closure}}::h11b550d560f5cc66
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:208:50
   9:        0x107e36709 - std::panicking::default_hook::he168e99d1cf91c3c
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:225:9
  10:        0x107e371fb - std::panicking::rust_panic_with_hook::hf87bfc4afef21ea6
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:591:17
  11:        0x107e18d27 - std::panicking::begin_panic::{{closure}}::h631923d2be23e79e
  12:        0x107e18998 - std::sys_common::backtrace::__rust_end_short_backtrace::h891b6a0b6f9c1b80
  13:        0x107e4bcfb - std::panicking::begin_panic::hd2dfddb0fed650c0
  14:        0x107e18aec - demo::d::h9d9ff8ddd5377da5
  15:        0x107e18ac9 - demo::c::haceeec3fee4323ba
  16:        0x107e18ab9 - demo::b::h4146166847508fc7
  17:        0x107e18aa9 - demo::a::h60d47e17615f49c4
  18:        0x107e18af9 - demo::main::h60dea0663d4b849d
  19:        0x107e18bea - core::ops::function::FnOnce::call_once::hf435db03deecd456
  20:        0x107e189cd - std::sys_common::backtrace::__rust_begin_short_backtrace::h936624db758e7870
  21:        0x107e194d0 - std::rt::lang_start::{{closure}}::ha060b13a4d59d3f5
  22:        0x107e37574 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h0e377e204feaadc3
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/core/src/ops/function.rs:259:13
  23:        0x107e37574 - std::panicking::try::do_call::h9c5b8eda90bbe0b7
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:379:40
  24:        0x107e37574 - std::panicking::try::he150bdff9d5b30f2
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:343:19
  25:        0x107e37574 - std::panic::catch_unwind::h04e9c415c0907892
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panic.rs:431:14
  26:        0x107e37574 - std::rt::lang_start_internal::h86f505dc7de50d93
                               at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/rt.rs:51:25
  27:        0x107e194a5 - std::rt::lang_start::h9d080ccd85b4c518
  28:        0x107e18b22 - _main

这是完整的堆栈跟踪。然而,这并不是很有用,因为它的大部分是语言内部。因此,在正常模式下,铁锈扫描堆栈的__rust_end_short_backtrace__rust_begin_short_backtrace函数。

这些函数什么都不做(因此,诡计阻止它们被优化掉),但是对于后台跟踪器来说,它们是生锈的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67444319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档