Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  backtrace.rs

  Sprache: Rust
 

#[cfg(backtrace)]
pub(crateuse std::backtrace::{Backtrace, BacktraceStatus};

#[cfg(all(not(backtrace), feature = "backtrace"))]
pub(crateuse self::capture::{Backtrace, BacktraceStatus};

#[cfg(not(any(backtrace, feature = "backtrace")))]
pub(crateenum Backtrace {}

#[cfg(backtrace)]
macro_rules! impl_backtrace {
    () => {
        std::backtrace::Backtrace
    };
}

#[cfg(all(not(backtrace), feature = "backtrace"))]
macro_rules! impl_backtrace {
    () => {
        impl core::fmt::Debug + core::fmt::Display
    };
}

#[cfg(any(backtrace, feature = "backtrace"))]
macro_rules! backtrace {
    () => {
        Some(crate::backtrace::Backtrace::capture())
    };
}

#[cfg(not(any(backtrace, feature = "backtrace")))]
macro_rules! backtrace {
    () => {
        None
    };
}

#[cfg(backtrace)]
macro_rules! backtrace_if_absent {
    ($err:expr) => {
        match ($err as &dyn std::error::Error).request_ref::<std::backtrace::Backtrace>() {
            Some(_) => None,
            None => backtrace!(),
        }
    };
}

#[cfg(all(feature = "std", not(backtrace), feature = "backtrace"))]
macro_rules! backtrace_if_absent {
    ($err:expr) => {
        backtrace!()
    };
}

#[cfg(all(feature = "std", not(backtrace), not(feature = "backtrace")))]
macro_rules! backtrace_if_absent {
    ($err:expr) => {
        None
    };
}

#[cfg(all(not(backtrace), feature = "backtrace"))]
mod capture {
    use backtrace::{BacktraceFmt, BytesOrWideString, Frame, PrintFmt, SymbolName};
    use core::cell::UnsafeCell;
    use core::fmt::{self, Debug, Display};
    use core::sync::atomic::{AtomicUsize, Ordering};
    use std::borrow::Cow;
    use std::env;
    use std::path::{self, Path, PathBuf};
    use std::sync::Once;

    pub(cratestruct Backtrace {
        inner: Inner,
    }

    pub(crateenum BacktraceStatus {
        Unsupported,
        Disabled,
        Captured,
    }

    enum Inner {
        Unsupported,
        Disabled,
        Captured(LazilyResolvedCapture),
    }

    struct Capture {
        actual_start: usize,
        resolved: bool,
        frames: Vec<BacktraceFrame>,
    }

    struct BacktraceFrame {
        frame: Frame,
        symbols: Vec<BacktraceSymbol>,
    }

    struct BacktraceSymbol {
        name: Option<Vec<u8>>,
        filename: Option<BytesOrWide>,
        lineno: Option<u32>,
        colno: Option<u32>,
    }

    enum BytesOrWide {
        Bytes(Vec<u8>),
        Wide(Vec<u16>),
    }

    impl Debug for Backtrace {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            let capture = match &self.inner {
                Inner::Unsupported => return fmt.write_str("<unsupported>"),
                Inner::Disabled => return fmt.write_str("<disabled>"),
                Inner::Captured(c) => c.force(),
            };

            let frames = &capture.frames[capture.actual_start..];

            write!(fmt, "Backtrace ")?;

            let mut dbg = fmt.debug_list();

            for frame in frames {
                if frame.frame.ip().is_null() {
                    continue;
                }

                dbg.entries(&frame.symbols);
            }

            dbg.finish()
        }
    }

    impl Debug for BacktraceFrame {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            let mut dbg = fmt.debug_list();
            dbg.entries(&self.symbols);
            dbg.finish()
        }
    }

    impl Debug for BacktraceSymbol {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            write!(fmt, "{{ ")?;

            if let Some(fn_name) = self.name.as_ref().map(|b| SymbolName::new(b)) {
                write!(fmt, "fn: \"{:#}\"", fn_name)?;
            } else {
                write!(fmt, "fn: <unknown>")?;
            }

            if let Some(fname) = self.filename.as_ref() {
                write!(fmt, ", file: \"{:?}\"", fname)?;
            }

            if let Some(line) = self.lineno {
                write!(fmt, ", line: {:?}", line)?;
            }

            write!(fmt, " }}")
        }
    }

    impl Debug for BytesOrWide {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            output_filename(
                fmt,
                match self {
                    BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
                    BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
                },
                PrintFmt::Short,
                env::current_dir().as_ref().ok(),
            )
        }
    }

    impl Backtrace {
        fn enabled() -> bool {
            static ENABLED: AtomicUsize = AtomicUsize::new(0);
            match ENABLED.load(Ordering::Relaxed) {
                0 => {}
                1 => return false,
                _ => return true,
            }
            let enabled = match env::var_os("RUST_LIB_BACKTRACE") {
                Some(s) => s != "0",
                None => match env::var_os("RUST_BACKTRACE") {
                    Some(s) => s != "0",
                    None => false,
                },
            };
            ENABLED.store(enabled as usize + 1, Ordering::Relaxed);
            enabled
        }

        #[inline(never)] // want to make sure there's a frame here to remove
        pub(cratefn capture() -> Backtrace {
            if Backtrace::enabled() {
                Backtrace::create(Backtrace::capture as usize)
            } else {
                let inner = Inner::Disabled;
                Backtrace { inner }
            }
        }

        // Capture a backtrace which starts just before the function addressed
        // by `ip`
        fn create(ip: usize) -> Backtrace {
            let mut frames = Vec::new();
            let mut actual_start = None;
            backtrace::trace(|frame| {
                frames.push(BacktraceFrame {
                    frame: frame.clone(),
                    symbols: Vec::new(),
                });
                if frame.symbol_address() as usize == ip && actual_start.is_none() {
                    actual_start = Some(frames.len() + 1);
                }
                true
            });

            // If no frames came out assume that this is an unsupported platform
            // since `backtrace` doesn't provide a way of learning this right
            // now, and this should be a good enough approximation.
            let inner = if frames.is_empty() {
                Inner::Unsupported
            } else {
                Inner::Captured(LazilyResolvedCapture::new(Capture {
                    actual_start: actual_start.unwrap_or(0),
                    frames,
                    resolved: false,
                }))
            };

            Backtrace { inner }
        }

        pub(cratefn status(&self) -> BacktraceStatus {
            match self.inner {
                Inner::Unsupported => BacktraceStatus::Unsupported,
                Inner::Disabled => BacktraceStatus::Disabled,
                Inner::Captured(_) => BacktraceStatus::Captured,
            }
        }
    }

    impl Display for Backtrace {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            let capture = match &self.inner {
                Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
                Inner::Disabled => return fmt.write_str("disabled backtrace"),
                Inner::Captured(c) => c.force(),
            };

            let full = fmt.alternate();
            let (frames, style) = if full {
                (&capture.frames[..], PrintFmt::Full)
            } else {
                (&capture.frames[capture.actual_start..], PrintFmt::Short)
            };

            // When printing paths we try to strip the cwd if it exists,
            // otherwise we just print the path as-is. Note that we also only do
            // this for the short format, because if it's full we presumably
            // want to print everything.
            let cwd = env::current_dir();
            let mut print_path = move |fmt: &mut fmt::Formatter, path: BytesOrWideString| {
                output_filename(fmt, path, style, cwd.as_ref().ok())
            };

            let mut f = BacktraceFmt::new(fmt, style, &mut print_path);
            f.add_context()?;
            for frame in frames {
                let mut f = f.frame();
                if frame.symbols.is_empty() {
                    f.print_raw(frame.frame.ip(), None, None, None)?;
                } else {
                    for symbol in frame.symbols.iter() {
                        f.print_raw_with_column(
                            frame.frame.ip(),
                            symbol.name.as_ref().map(|b| SymbolName::new(b)),
                            symbol.filename.as_ref().map(|b| match b {
                                BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
                                BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
                            }),
                            symbol.lineno,
                            symbol.colno,
                        )?;
                    }
                }
            }
            f.finish()?;
            Ok(())
        }
    }

    struct LazilyResolvedCapture {
        sync: Once,
        capture: UnsafeCell<Capture>,
    }

    impl LazilyResolvedCapture {
        fn new(capture: Capture) -> Self {
            LazilyResolvedCapture {
                sync: Once::new(),
                capture: UnsafeCell::new(capture),
            }
        }

        fn force(&self) -> &Capture {
            self.sync.call_once(|| {
                // Safety: This exclusive reference can't overlap with any
                // others. `Once` guarantees callers will block until this
                // closure returns. `Once` also guarantees only a single caller
                // will enter this closure.
                unsafe { &mut *self.capture.get() }.resolve();
            });

            // Safety: This shared reference can't overlap with the exclusive
            // reference above.
            unsafe { &*self.capture.get() }
        }
    }

    // Safety: Access to the inner value is synchronized using a thread-safe
    // `Once`. So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too
    unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {}

    impl Capture {
        fn resolve(&mut self) {
            // If we're already resolved, nothing to do!
            if self.resolved {
                return;
            }
            self.resolved = true;

            for frame in self.frames.iter_mut() {
                let symbols = &mut frame.symbols;
                let frame = &frame.frame;
                backtrace::resolve_frame(frame, |symbol| {
                    symbols.push(BacktraceSymbol {
                        name: symbol.name().map(|m| m.as_bytes().to_vec()),
                        filename: symbol.filename_raw().map(|b| match b {
                            BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
                            BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
                        }),
                        lineno: symbol.lineno(),
                        colno: symbol.colno(),
                    });
                });
            }
        }
    }

    // Prints the filename of the backtrace frame.
    fn output_filename(
        fmt: &mut fmt::Formatter,
        bows: BytesOrWideString,
        print_fmt: PrintFmt,
        cwd: Option<&PathBuf>,
    ) -> fmt::Result {
        let file: Cow<Path> = match bows {
            #[cfg(unix)]
            BytesOrWideString::Bytes(bytes) => {
                use std::os::unix::ffi::OsStrExt;
                Path::new(std::ffi::OsStr::from_bytes(bytes)).into()
            }
            #[cfg(not(unix))]
            BytesOrWideString::Bytes(bytes) => {
                Path::new(std::str::from_utf8(bytes).unwrap_or("<unknown>")).into()
            }
            #[cfg(windows)]
            BytesOrWideString::Wide(wide) => {
                use std::os::windows::ffi::OsStringExt;
                Cow::Owned(std::ffi::OsString::from_wide(wide).into())
            }
            #[cfg(not(windows))]
            BytesOrWideString::Wide(_wide) => Path::new("<unknown>").into(),
        };
        if print_fmt == PrintFmt::Short && file.is_absolute() {
            if let Some(cwd) = cwd {
                if let Ok(stripped) = file.strip_prefix(&cwd) {
                    if let Some(s) = stripped.to_str() {
                        return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s);
                    }
                }
            }
        }
        Display::fmt(&file.display(), fmt)
    }
}

fn _assert_send_sync() {
    fn _assert<T: Send + Sync>() {}
    _assert::<Backtrace>();
}

Messung V0.5 in Prozent
C=92 H=95 G=93

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-06-19) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik