Skip to content

improve RUST_BACKTRACE panic output #37783

Closed
@vvuk

Description

@vvuk

Currently RUST_BACKTRACE output includes a lot of noise, making it hard to see the actual issue. For example:

stack backtrace:
   1:     0x7f69d5ba46da - std::sys::imp::backtrace::tracing::imp::write::he3d1bfbdbf113480
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42

   2:     0x7f69d5baae2f - std::panicking::default_hook::{{closure}}::h575f1b40d2e88f07
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:247
   3:     0x7f69d5ba90c6 - std::panicking::default_hook::h3d5dccce8125d0cf
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:263
   4:     0x7f69d5ba9777 - std::panicking::rust_panic_with_hook::h00b81bb3dcbd51f2
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:451
   5:     0x7f69d5ba9604 - std::panicking::begin_panic::ha6a0d553db9869ff
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:413
   6:     0x7f69d5ba9529 - std::panicking::begin_panic_fmt::h24d113aee3ee4081
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:397
   7:     0x7f69d5ba94b7 - rust_begin_unwind
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:373
   8:     0x7f69d5be55fd - core::panicking::panic_fmt::he441b2ea2036b98a
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libcore/panicking.rs:69
   9:     0x7f69d5ab93ea - core::result::unwrap_failed::h9123c8d5ed329cea
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libcore/macros.rs:29
  10:     0x7f69d5a7a485 - <core::result::Result<T, E>>::unwrap::had74dea202030e74
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libcore/result.rs:737
  11:     0x7f69d5b635bf - ipc_channel::platform::test::try_recv_large_delayed::{{closure}}::{{closure}}::h2e33a5fda2c9d793
                        at /home/vladimir/proj/ipc-channel/src/platform/test.rs:719
  12:     0x7f69d5b0472a - <std::panic::AssertUnwindSafe<F> as core::ops::FnOnce<()>>::call_once::h67930f1a73be51d8
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panic.rs:295
  13:     0x7f69d5a5f087 - std::panicking::try::do_call::h8e541b07456941e1
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:356
  14:     0x7f69d5bb290a - __rust_maybe_catch_panic
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libpanic_unwind/lib.rs:97
  15:     0x7f69d5a5b6d6 - std::panicking::try::h385588122564e243
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:332
  16:     0x7f69d5a4e70e - std::panic::catch_unwind::h7e92894a4b479185
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panic.rs:351
  17:     0x7f69d5b52940 - std::thread::Builder::spawn::{{closure}}::h6c1a6bd520337fe4
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/thread/mod.rs:287
  18:     0x7f69d5ac32be - <F as alloc::boxed::FnBox<A>>::call_box::h606bb70e048e1567
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/liballoc/boxed.rs:595
  19:     0x7f69d5ba87c4 - std::sys::imp::thread::Thread::new::thread_start::h990fb082eb5abe34
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/liballoc/boxed.rs:605
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/sys_common/thread.rs:21
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/sys/unix/thread.rs:84
  20:     0x7f69d51d8183 - start_thread
  21:     0x7f69d4cda37c - clone
  22:                0x0 - <unknown>

The only actually relevant items start at 9 and go on down, up until 12 or so. Out of 45 lines, only 8 are actually useful! The ones after 12 are just noise and don't hurt much, but the ones at the top make it far more difficult to read. Combine this with the long filenames as a result of standard library pathnames, and RUST_BACKTRACE output is super noisy. Instead, we could do a few things...

(1) Save the rust source location as part of the libstd build and strip it from all output filenames. This would be "/buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../" and would significantly improve the output:

stack backtrace:
   1:     0x7f69d5ba46da - std::sys::imp::backtrace::tracing::imp::write::he3d1bfbdbf113480
                        at libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
   2:     0x7f69d5baae2f - std::panicking::default_hook::{{closure}}::h575f1b40d2e88f07
                        at libstd/panicking.rs:247
   3:     0x7f69d5ba90c6 - std::panicking::default_hook::h3d5dccce8125d0cf
                        at libstd/panicking.rs:263
   4:     0x7f69d5ba9777 - std::panicking::rust_panic_with_hook::h00b81bb3dcbd51f2
                        at libstd/panicking.rs:451
   5:     0x7f69d5ba9604 - std::panicking::begin_panic::ha6a0d553db9869ff
                        at libstd/panicking.rs:413
   6:     0x7f69d5ba9529 - std::panicking::begin_panic_fmt::h24d113aee3ee4081
                        at libstd/panicking.rs:397
   7:     0x7f69d5ba94b7 - rust_begin_unwind
                        at libstd/panicking.rs:373
   8:     0x7f69d5be55fd - core::panicking::panic_fmt::he441b2ea2036b98a
                        at libcore/panicking.rs:69
   9:     0x7f69d5ab93ea - core::result::unwrap_failed::h9123c8d5ed329cea
                        at libcore/macros.rs:29
  10:     0x7f69d5a7a485 - <core::result::Result<T, E>>::unwrap::had74dea202030e74
                        at libcore/result.rs:737
  11:     0x7f69d5b635bf - ipc_channel::platform::test::try_recv_large_delayed::{{closure}}::{{closure}}::h2e33a5fda2c9d793
                        at /home/vladimir/proj/ipc-channel/src/platform/test.rs:719
  12:     0x7f69d5b0472a - <std::panic::AssertUnwindSafe<F> as core::ops::FnOnce<()>>::call_once::h67930f1a73be51d8
                        at libstd/panic.rs:295
  13:     0x7f69d5a5f087 - std::panicking::try::do_call::h8e541b07456941e1
                        at libstd/panicking.rs:356
  14:     0x7f69d5bb290a - __rust_maybe_catch_panic
                        at libpanic_unwind/lib.rs:97
  15:     0x7f69d5a5b6d6 - std::panicking::try::h385588122564e243
                        at libstd/panicking.rs:332
  16:     0x7f69d5a4e70e - std::panic::catch_unwind::h7e92894a4b479185
                        at libstd/panic.rs:351
  17:     0x7f69d5b52940 - std::thread::Builder::spawn::{{closure}}::h6c1a6bd520337fe4
                        at libstd/thread/mod.rs:287
  18:     0x7f69d5ac32be - <F as alloc::boxed::FnBox<A>>::call_box::h606bb70e048e1567
                        at liballoc/boxed.rs:595
  19:     0x7f69d5ba87c4 - std::sys::imp::thread::Thread::new::thread_start::h990fb082eb5abe34
                        at liballoc/boxed.rs:605
                        at libstd/sys_common/thread.rs:21
                        at libstd/sys/unix/thread.rs:84
  20:     0x7f69d51d8183 - start_thread
  21:     0x7f69d4cda37c - clone
  22:                0x0 - <unknown>

(2) But the forced (accidental?) alignment makes it hard to scan down the list of functions, so now that we shortened things, we can push the file/line number further right making it much easier to visually scan to find the parts that we care about:

   1:     0x7f69d5ba46da - std::sys::imp::backtrace::tracing::imp::write::he3d1bfbdbf113480
                                at libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
   2:     0x7f69d5baae2f - std::panicking::default_hook::{{closure}}::h575f1b40d2e88f07
                                at libstd/panicking.rs:247
   3:     0x7f69d5ba90c6 - std::panicking::default_hook::h3d5dccce8125d0cf
                                at libstd/panicking.rs:263
   4:     0x7f69d5ba9777 - std::panicking::rust_panic_with_hook::h00b81bb3dcbd51f2
                                at libstd/panicking.rs:451
   5:     0x7f69d5ba9604 - std::panicking::begin_panic::ha6a0d553db9869ff
                                at libstd/panicking.rs:413
   6:     0x7f69d5ba9529 - std::panicking::begin_panic_fmt::h24d113aee3ee4081
                                at libstd/panicking.rs:397
   7:     0x7f69d5ba94b7 - rust_begin_unwind
                                at libstd/panicking.rs:373
   8:     0x7f69d5be55fd - core::panicking::panic_fmt::he441b2ea2036b98a
                                at libcore/panicking.rs:69
   9:     0x7f69d5ab93ea - core::result::unwrap_failed::h9123c8d5ed329cea
                                at libcore/macros.rs:29
  10:     0x7f69d5a7a485 - <core::result::Result<T, E>>::unwrap::had74dea202030e74
                                at libcore/result.rs:737
  11:     0x7f69d5b635bf - ipc_channel::platform::test::try_recv_large_delayed::{{closure}}::{{closure}}::h2e33a5fda2c9d793
                                at /home/vladimir/proj/ipc-channel/src/platform/test.rs:719
  12:     0x7f69d5b0472a - <std::panic::AssertUnwindSafe<F> as core::ops::FnOnce<()>>::call_once::h67930f1a73be51d8
                                at libstd/panic.rs:295
...

(3) Let's decide to give ourselves 120 columns to work with, and put the file/line on the same line if possible:

   1:     0x7f69d5ba46da - std::sys::imp::backtrace::tracing::imp::write::he3d1bfbdbf113480
                                at libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
   2:     0x7f69d5baae2f - std::panicking::default_hook::{{closure}}::h575f1b40d2e88f07 at libstd/panicking.rs:247
   3:     0x7f69d5ba90c6 - std::panicking::default_hook::h3d5dccce8125d0cf at libstd/panicking.rs:263
   4:     0x7f69d5ba9777 - std::panicking::rust_panic_with_hook::h00b81bb3dcbd51f2 at libstd/panicking.rs:451
   5:     0x7f69d5ba9604 - std::panicking::begin_panic::ha6a0d553db9869ff at libstd/panicking.rs:413
   6:     0x7f69d5ba9529 - std::panicking::begin_panic_fmt::h24d113aee3ee4081 at libstd/panicking.rs:397
   7:     0x7f69d5ba94b7 - rust_begin_unwind at libstd/panicking.rs:373
   8:     0x7f69d5be55fd - core::panicking::panic_fmt::he441b2ea2036b98a at libcore/panicking.rs:69
   9:     0x7f69d5ab93ea - core::result::unwrap_failed::h9123c8d5ed329cea at libcore/macros.rs:29
  10:     0x7f69d5a7a485 - <core::result::Result<T, E>>::unwrap::had74dea202030e74 at libcore/result.rs:737
  11:     0x7f69d5b635bf - ipc_channel::platform::test::try_recv_large_delayed::{{closure}}::{{closure}}::h2e33a5fda2c9d793
                                at /home/vladimir/proj/ipc-channel/src/platform/test.rs:719
  12:     0x7f69d5b0472a - <std::panic::AssertUnwindSafe<F> as core::ops::FnOnce<()>>::call_once::h67930f1a73be51d8
                                at libstd/panic.rs:295

(4) Much better, but frames 1-8 are still totally worthless. We know that calls to panic!() are going to go through either panicking::panic or panicking::panic_fmt. So, when doing a backtrace, let's skip all frames until we see one of those frames:

{ skipping 8 frames... }
   9:     0x7f69d5ab93ea - core::result::unwrap_failed::h9123c8d5ed329cea at libcore/macros.rs:29
  10:     0x7f69d5a7a485 - <core::result::Result<T, E>>::unwrap::had74dea202030e74 at libcore/result.rs:737
  11:     0x7f69d5b635bf - ipc_channel::platform::test::try_recv_large_delayed::{{closure}}::{{closure}}::h2e33a5fda2c9d793
                                at /home/vladimir/proj/ipc-channel/src/platform/test.rs:719
  12:     0x7f69d5b0472a - <std::panic::AssertUnwindSafe<F> as core::ops::FnOnce<()>>::call_once::h67930f1a73be51d8
                                at libstd/panic.rs:295
  13:     0x7f69d5a5f087 - std::panicking::try::do_call::h8e541b07456941e1 at libstd/panicking.rs:356
  14:     0x7f69d5bb290a - __rust_maybe_catch_panic at libpanic_unwind/lib.rs:97
  15:     0x7f69d5a5b6d6 - std::panicking::try::h385588122564e243 at libstd/panicking.rs:332
  16:     0x7f69d5a4e70e - std::panic::catch_unwind::h7e92894a4b479185 at libstd/panic.rs:351
  17:     0x7f69d5b52940 - std::thread::Builder::spawn::{{closure}}::h6c1a6bd520337fe4 at libstd/thread/mod.rs:287
  18:     0x7f69d5ac32be - <F as alloc::boxed::FnBox<A>>::call_box::h606bb70e048e1567 at liballoc/boxed.rs:595
  19:     0x7f69d5ba87c4 - std::sys::imp::thread::Thread::new::thread_start::h990fb082eb5abe34
                                at liballoc/boxed.rs:605
                                at libstd/sys_common/thread.rs:21
                                at libstd/sys/unix/thread.rs:84
  20:     0x7f69d51d8183 - start_thread
  21:     0x7f69d4cda37c - clone
  22:                0x0 - <unknown>

Finally, we could disable all the output optimizations via RUST_BACKTRACE=2 or similar, so that if there are any tools that want a consistent format to deal with, they can still get it.

I'm happy to hack on this if there's interest.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions