Repository: tokio-rs/tokio
File: tokio/src/runtime/dump.rs (Rust)

Code before:
    /// The exact backtraces included here are unstable and might change in the future,
    /// but you can expect one [`Backtrace`] for every call to
    /// [`poll`] to a bottom-level Tokio future - so if something like [`join!`] is
    /// used, there will be a backtrace for each future in the join.
    ///
    /// [`poll`]: std::future::Future::poll
    /// [`join!`]: macro@join
    pub fn resolve_backtraces(&self) -> Vec<Backtrace> {
        self.inner
            .backtraces()
            .iter()
            .map(|backtrace| {
                let mut backtrace = backtrace::Backtrace::from(backtrace.clone());
                backtrace.resolve();
                Backtrace {
                    frames: backtrace
                        .frames()
                        .iter()
                        .map(BacktraceFrame::from_resolved_backtrace_frame)
                        .collect(),
                }
            })
            .collect()
    }

    /// Runs the function `f` in tracing mode, and returns its result along with the resulting [`Trace`].
    ///
    /// The passed-in function is normally a poll function. Due to the way tracing is implemented,
    /// Tokio leaf futures might, instead of doing their actual work, do the equivalent of a
    /// `yield_now` (returning a `Poll::Pending` and scheduling the current context for execution),
    /// which means forward progress is only guaranteed if you eventually call your future outside of
    /// `capture`.
    ///
    /// Example usage:
    /// ```
    /// use std::future::Future;
    /// use std::task::Poll;
    /// use tokio::runtime::dump::Trace;
    ///
    /// # async fn test_fn() {
    /// // some future
    /// let mut test_future = std::pin::pin!(async move { tokio::task::yield_now().await; 0 });
    ///
    /// // trace it once
    /// let (trace, res) = Trace::root(std::future::poll_fn(|cx| {
    ///     let (res, trace) = Trace::capture(|| test_future.as_mut().poll(cx));
    ///     Poll::Ready((trace, res))
    /// })).await;
    ///
    /// let output = match res {
    ///    Poll::Ready(output) => output,

Review comment (suggestion):
This documentation captures the *what*, but not the *why*. When would I want to call this instead of `Handle::dump`?

Similarly, the documentation for `Handle::dump` should be extended to mention that `capture` and `root` should be used for self-tracing. 

Code after:
    /// The exact backtraces included here are unstable and might change in the future,
    /// but you can expect one [`Backtrace`] for every call to
    /// [`poll`] to a bottom-level Tokio future - so if something like [`join!`] is
    /// used, there will be a backtrace for each future in the join.
    ///
    /// [`poll`]: std::future::Future::poll
    /// [`join!`]: macro@join
    pub fn resolve_backtraces(&self) -> Vec<Backtrace> {
        self.inner
            .backtraces()
            .iter()
            .map(|backtrace| {
                let mut backtrace = backtrace::Backtrace::from(backtrace.clone());
                backtrace.resolve();
                Backtrace {
                    frames: backtrace
                        .frames()
                        .iter()
                        .map(BacktraceFrame::from_resolved_backtrace_frame)
                        .collect(),
                }
            })
            .collect()
    }

    /// Runs the function `f` in tracing mode, and returns its result along with the resulting [`Trace`].
    ///
    /// This is normally called with `f` being the poll function of a future, and will give you a backtrace
    /// that tells you what that one future is doing.
    ///
    /// Use [`Handle::dump`] instead if you want to know what *all the tasks* in your program are doing.
    /// Also see [`Handle::dump`] for more documentation about dumps, but unlike [`Handle::dump`], this function
    /// should not be much slower than calling `f` directly.
    ///
    /// Due to the way tracing is implemented, Tokio leaf futures will usually, instead of doing their
    /// actual work, do the equivalent of a `yield_now` (returning a `Poll::Pending` and scheduling the
    /// current context for execution), which means forward progress will probably not happen unless
    /// you eventually call your future outside of `capture`.
    ///
    /// [`Handle::dump`]: crate::runtime::Handle::dump
    ///
    /// Example usage:
    /// ```
    /// use std::future::Future;
    /// use std::task::Poll;
    /// use tokio::runtime::dump::Trace;
    ///
    /// # async fn test_fn() {
    /// // some future
    /// let mut test_future = std::pin::pin!(async move { tokio::task::yield_now().await; 0 });
    ///