about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authoronur-ozkan <work@onurozkan.dev>2025-05-04 16:41:42 +0300
committeronur-ozkan <work@onurozkan.dev>2025-05-04 17:18:27 +0300
commitde44231d22eea1d1d27fab8d020557323996bb52 (patch)
treed8fe92fff157cad14ed6b2b7a15154de253424a0 /src
parent6e23095adf9209614a45f7f75fea36dad7b92afb (diff)
downloadrust-de44231d22eea1d1d27fab8d020557323996bb52.tar.gz
rust-de44231d22eea1d1d27fab8d020557323996bb52.zip
implement `PanicTracker` to track `t` panics
Trying to understand panics triggered by `t` macro calls is very exhausting (especially on CI failures)
because it doesn't provide any information about where the macro was originally invoked. This change adds
that missing information when an inner call inside the `t` macro panics.

Signed-off-by: onur-ozkan <work@onurozkan.dev>
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/lib.rs1
-rw-r--r--src/bootstrap/src/utils/helpers.rs30
2 files changed, 26 insertions, 5 deletions
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 88d181532a7..1e6acad5c0f 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -53,6 +53,7 @@ use tracing::{instrument, span};
 pub use utils::change_tracker::{
     CONFIG_CHANGE_HISTORY, find_recent_config_change_ids, human_readable_changes,
 };
+pub use utils::helpers::PanicTracker;
 
 use crate::core::build_steps::vendor::VENDOR_DIR;
 
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 1299fbb7d62..b31b2757767 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -7,8 +7,9 @@ use std::ffi::OsStr;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::sync::OnceLock;
+use std::thread::panicking;
 use std::time::{Instant, SystemTime, UNIX_EPOCH};
-use std::{env, fs, io, str};
+use std::{env, fs, io, panic, str};
 
 use build_helper::util::fail;
 use object::read::archive::ArchiveFile;
@@ -22,6 +23,23 @@ pub use crate::utils::shared_helpers::{dylib_path, dylib_path_var};
 #[cfg(test)]
 mod tests;
 
+/// A wrapper around `std::panic::Location` used to track the location of panics
+/// triggered by `t` macro usage.
+pub struct PanicTracker<'a>(pub &'a panic::Location<'a>);
+
+impl Drop for PanicTracker<'_> {
+    fn drop(&mut self) {
+        if panicking() {
+            eprintln!(
+                "Panic was initiated from {}:{}:{}",
+                self.0.file(),
+                self.0.line(),
+                self.0.column()
+            );
+        }
+    }
+}
+
 /// A helper macro to `unwrap` a result except also print out details like:
 ///
 /// * The file/line of the panic
@@ -32,19 +50,21 @@ mod tests;
 /// using a `Result` with `try!`, but this may change one day...
 #[macro_export]
 macro_rules! t {
-    ($e:expr) => {
+    ($e:expr) => {{
+        let _panic_guard = $crate::PanicTracker(std::panic::Location::caller());
         match $e {
             Ok(e) => e,
             Err(e) => panic!("{} failed with {}", stringify!($e), e),
         }
-    };
+    }};
     // it can show extra info in the second parameter
-    ($e:expr, $extra:expr) => {
+    ($e:expr, $extra:expr) => {{
+        let _panic_guard = $crate::PanicTracker(std::panic::Location::caller());
         match $e {
             Ok(e) => e,
             Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra),
         }
-    };
+    }};
 }
 
 pub use t;