diff --git a/Cargo.lock b/Cargo.lock index ea23a4a..62dc8e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,301 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "smallvec" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test-program" +version = "0.1.0" +dependencies = [ + "tracing", + "tracing-subscriber", + "tracing-tree", + "uwuwind", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tracing-tree" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ec6adcab41b1391b08a308cc6302b79f8095d1673f6947c2dc65ffb028b0b2d" +dependencies = [ + "nu-ansi-term", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + [[package]] name = "uwuwind" version = "0.1.0" dependencies = [ "libc", + "tracing", ] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index bd1d84a..6f401be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +members = ["test-program"] [package] name = "uwuwind" @@ -9,6 +10,7 @@ edition = "2021" [dependencies] libc = { version = "0.2.140", default-features = false, features = ["extra_traits"] } +tracing = { version = "0.1.40", default-features = false, features = ["attributes"] } [profile.dev] # the test binary needs uwutables diff --git a/src/dwarf/divination.rs b/src/dwarf/divination.rs index 392b9c8..958f5d7 100644 --- a/src/dwarf/divination.rs +++ b/src/dwarf/divination.rs @@ -45,6 +45,7 @@ struct EhFrameHeader { table_enc: Encoding, } +#[instrument] fn eh_frame_hdr_ptr(addr: Addr) -> Option<*const EhFrameHeader> { unsafe { let mut out = core::mem::zeroed(); @@ -76,6 +77,7 @@ fn eh_frame_hdr_ptr(addr: Addr) -> Option<*const EhFrameHeader> { } } +#[instrument] pub(crate) fn eh_frame(addr: Addr) -> Option<*const u8> { unsafe { let ptr = eh_frame_hdr_ptr(addr)?; @@ -89,7 +91,7 @@ pub(crate) fn eh_frame(addr: Addr) -> Option<*const u8> { return None; } - trace!("eh_frame_hdr: {:#?}", header); + trace!("eh_frame_hdr: {:?}", header); let (read_size, eh_frame_ptr) = read_encoded(ptr, header.eh_frame_ptr_enc); let ptr = ptr.add(read_size); diff --git a/src/dwarf/mod.rs b/src/dwarf/mod.rs index 595bd5f..957f146 100644 --- a/src/dwarf/mod.rs +++ b/src/dwarf/mod.rs @@ -14,6 +14,7 @@ pub(crate) use divination::eh_frame; /// The `.eh_frame` section contains a list of call frame information records. /// Each CFI contains a CIE followed be one or more FDE records. +#[instrument] pub unsafe fn uwutables(eh_frame: *const u8) { trace!("getting uwutables from {:p}", eh_frame); unsafe { diff --git a/src/dwarf/parse.rs b/src/dwarf/parse.rs index 67e248e..017f56c 100644 --- a/src/dwarf/parse.rs +++ b/src/dwarf/parse.rs @@ -526,6 +526,7 @@ fn read_ileb128(data: &mut Cursor<'_>) -> Result { Ok(result) } +#[instrument(ret)] unsafe fn parse_frame_info<'a>( ptr: *const u8, ) -> Result<(Cie<'a>, alloc::vec::Vec>, *const u8)> { @@ -566,6 +567,7 @@ unsafe fn parse_frame_head<'a>(ptr: *const u8) -> Result<(u32, &'a [u8], *const Ok((cie_id, data.0, new_ptr)) } +#[instrument(skip(data))] fn parse_cie<'a>(data: &mut Cursor<'a>) -> Result> { let version = read_u8(data)?; if version != 1 { @@ -604,6 +606,7 @@ fn parse_cie<'a>(data: &mut Cursor<'a>) -> Result> { Ok(cie) } +#[instrument(skip(data))] fn parse_fde<'a>(data: &mut Cursor<'a>, cie_id: u32, cie: &Cie<'_>) -> Result> { trace!("FDE {:x?}", data.0); diff --git a/src/lib.rs b/src/lib.rs index 1dde324..c36fd3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,10 +3,11 @@ extern crate alloc; +#[macro_use] +extern crate tracing; + use core::{ffi, sync::atomic::AtomicPtr}; -// Get the macros into our local prelude. -#[macro_use] mod stdext; pub mod uw; @@ -30,7 +31,8 @@ impl Addr { pub unsafe extern "C" fn _UnwindRaiseException( exception_object: *mut uw::_Unwind_Exception, ) -> uw::_Unwind_Reason_Code { - trace!("someone raised an exception with addr {exception_object:p}"); + let _span = info_span!("_UnwindRaiseException", ?exception_object).entered(); + let eh_frame = crate::dwarf::eh_frame(arch::get_rip()).unwrap(); crate::dwarf::uwutables(eh_frame); diff --git a/src/stdext.rs b/src/stdext.rs index 4222fed..b461011 100644 --- a/src/stdext.rs +++ b/src/stdext.rs @@ -21,19 +21,6 @@ pub fn print(args: fmt::Arguments<'_>) -> fmt::Result { write!(LibCStdoutWriter, "{}", args) } -macro_rules! trace { - ($($tt:tt)*) => { - // We separate out the format_args for rust-analyzer support. - match format_args!($($tt)*) { - args => { - $crate::stdext::print(::core::format_args!("UWUWIND TRACE | uwuwind/{}:{}: {}\n", file!(), line!(), args)).expect("failed to trace") - } - } - }; -} - -pub(crate) use trace; - pub(crate) fn abort() -> ! { // SAFETY: We abort. unsafe { libc::abort() }; diff --git a/src/walk/fp.rs b/src/walk/fp.rs index a3b909d..09f8bfd 100644 --- a/src/walk/fp.rs +++ b/src/walk/fp.rs @@ -1,6 +1,6 @@ //! Test frame pointer walker. Not very good. -use crate::{arch::get_rbp, stdext::trace}; +use crate::arch::get_rbp; pub(crate) unsafe fn walk() { let mut current_rbp = get_rbp().0.cast::(); diff --git a/test-program/Cargo.toml b/test-program/Cargo.toml new file mode 100644 index 0000000..4f7e195 --- /dev/null +++ b/test-program/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "test-program" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tracing = "0.1.40" +tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } +tracing-tree = "0.2.5" +uwuwind = { path = ".." } diff --git a/src/main.rs b/test-program/src/main.rs similarity index 63% rename from src/main.rs rename to test-program/src/main.rs index dcdde56..d117962 100644 --- a/src/main.rs +++ b/test-program/src/main.rs @@ -1,3 +1,5 @@ +use tracing_subscriber::{layer::SubscriberExt, EnvFilter}; +use tracing_subscriber::util::SubscriberInitExt; use uwuwind::uw; #[repr(C)] @@ -7,6 +9,18 @@ struct Exception { } fn main() { + let registry = tracing_subscriber::Registry::default().with( + EnvFilter::builder() + .with_default_directive(tracing::Level::TRACE.into()) + .from_env() + .unwrap(), + ); + + let tree_layer = tracing_tree::HierarchicalLayer::new(2) + .with_targets(true) + .with_bracketed_fields(true); + + registry.with(tree_layer).init(); unsafe { uwuwind::set_personality_routine(personality_routine);