From a37b02058b5faf78cf2c49be474c35f292b5bef0 Mon Sep 17 00:00:00 2001 From: Henri Autio Date: Fri, 13 Mar 2026 12:43:17 -0700 Subject: [PATCH] =?UTF-8?q?1.=20Early=20filtering=20in=20find=5Fstatic=5Fv?= =?UTF-8?q?ariables()=20=E2=80=94=20Added=20an=20optional=20symbol=5Ffilte?= =?UTF-8?q?r:=20Option<&HashMap<&str,=20Option>>=20parameter.?= =?UTF-8?q?=20When=20provided,=20each=20DW=5FTAG=5Fvariable's=20linkage=20?= =?UTF-8?q?name=20is=20checked=20against=20the=20HashMap=20before=20the=20?= =?UTF-8?q?expensive=20read=5Fvariable=5Fentry()=20call=20(type=20resoluti?= =?UTF-8?q?on,=20location=20evaluation,=20data=20reading).=20Variables=20d?= =?UTF-8?q?estined=20to=20be=20filtered=20out=20(defmt=20symbols,=20LTO-re?= =?UTF-8?q?moved=20symbols)=20are=20now=20skipped=20entirely.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2. O(1) symbol lookups — In trace_inner(), a HashMap<&str, Option> is built once from all ELF symbols and passed into find_static_variables(), replacing the old O(n×m) elf.symbol_by_name() retain loop. 3. trace_no_statics() / --no-statics flag — Added trace_no_statics() entry point that skips statics entirely for cases where they're not needed. --- trace/Cargo.lock | 669 +++++++++++++++++++++++++++++++++++++ trace/Cargo.toml | 93 ++++-- trace/src/platform/mod.rs | 115 ++++--- trace/src/variables/mod.rs | 21 ++ 4 files changed, 817 insertions(+), 81 deletions(-) create mode 100644 trace/Cargo.lock diff --git a/trace/Cargo.lock b/trace/Cargo.lock new file mode 100644 index 0000000..14c6d0a --- /dev/null +++ b/trace/Cargo.lock @@ -0,0 +1,669 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9acbfca36652500c911ddb767ed433e3ed99b032b5d935be73c6923662db1d43" +dependencies = [ + "cpp_demangle", + "fallible-iterator", + "gimli", + "memmap2", + "object", + "rustc-demangle", + "smallvec", + "typed-arena", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + +[[package]] +name = "colored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "cpp_demangle" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "flate2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "gimli" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "memmap2" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28" +dependencies = [ + "libc", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a" +dependencies = [ + "flate2", + "memchr", + "ruzstd", +] + +[[package]] +name = "phf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_generator" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cbb1126afed61dd6368748dae63b1ee7dc480191c6262a3b4ff1e29d86a6c5b" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d713258393a82f091ead52047ca779d37e5766226d009de21696c4e667044368" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" +dependencies = [ + "siphasher", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rustc-demangle" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" + +[[package]] +name = "ruzstd" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640bec8aad418d7d03c72ea2de10d5c646a598f9883c7babc160d91e3c1b26c" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "simple_logger" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c5dfa5e08767553704aa0ffd9d9794d527103c736aba9854773851fd7497eb" +dependencies = [ + "colored 2.2.0", + "log", + "time", + "windows-sys 0.48.0", +] + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stackdump-core" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b23f213e6d8861be0eb703b14af0501e3476390d27395c142500884afc08924" +dependencies = [ + "arrayvec", + "funty", + "gimli", + "serde", +] + +[[package]] +name = "stackdump-trace" +version = "0.10.5" +dependencies = [ + "addr2line", + "bitvec", + "colored 3.0.0", + "funty", + "gimli", + "log", + "object", + "phf", + "simple_logger", + "stackdump-core", + "strum", + "strum_macros", + "thiserror", + "trees", +] + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "trees" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de5f738ceab88e2491a94ddc33c3feeadfa95fedc60363ef110845df12f3878" + +[[package]] +name = "twox-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b907da542cbced5261bd3256de1b3a1bf340a3d37f93425a07362a1d687de56" + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] diff --git a/trace/Cargo.toml b/trace/Cargo.toml index aeb83c1..21ffb0b 100644 --- a/trace/Cargo.toml +++ b/trace/Cargo.toml @@ -1,29 +1,76 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + [package] -name = "stackdump-trace" -version.workspace = true edition = "2021" -license = "MIT OR Apache-2.0" +name = "stackdump-trace" +version = "0.10.5" +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Crate for tracing stack dumps" homepage = "https://github.com/tweedegolf/stackdump" -repository = "https://github.com/tweedegolf/stackdump" readme = "README.md" -keywords = [ "stackdump"] +keywords = ["stackdump"] categories = ["embedded"] -description = "Crate for tracing stack dumps" +license = "MIT OR Apache-2.0" +repository = "https://github.com/tweedegolf/stackdump" + +[lib] +name = "stackdump_trace" +path = "src/lib.rs" + +[dependencies.addr2line] +version = "0.25.0" + +[dependencies.bitvec] +version = "1.0.0" + +[dependencies.colored] +version = "3.0.0" + +[dependencies.funty] +version = "2.0.0" +default-features = false + +[dependencies.gimli] +version = "0.32.0" + +[dependencies.log] +version = "0.4.14" + +[dependencies.object] +version = "0.37.1" + +[dependencies.phf] +version = "0.12.1" +features = ["macros"] + +[dependencies.stackdump-core] +version = "0.10.5" + +[dependencies.strum] +version = "0.27.2" + +[dependencies.strum_macros] +version = "0.27.2" + +[dependencies.thiserror] +version = "2.0.12" + +[dependencies.trees] +version = "0.4.2" -[dependencies] -addr2line = "0.25.0" -gimli = "0.32.0" -object = "0.37.1" -bitvec = "1.0.0" -stackdump-core = { version = "0.10.5", path = "../core" } -thiserror = "2.0.12" -log = "0.4.14" -trees = "0.4.2" -colored = "3.0.0" -phf = { version = "0.12.1", features = ["macros"] } -funty = { version = "2.0.0", default-features = false } -strum = "0.27.2" -strum_macros = "0.27.2" - -[dev-dependencies] -simple_logger = "5.0.0" +[dev-dependencies.simple_logger] +version = "5.0.0" diff --git a/trace/src/platform/mod.rs b/trace/src/platform/mod.rs index 1d4d3af..1f2cee7 100644 --- a/trace/src/platform/mod.rs +++ b/trace/src/platform/mod.rs @@ -5,6 +5,7 @@ use object::{Object, ObjectSection, ObjectSymbol, SectionKind}; use stackdump_core::{device_memory::DeviceMemory, memory_region::VecMemoryRegion}; use std::collections::HashMap; + pub mod cortex_m; /// The result of an unwinding procedure @@ -50,8 +51,31 @@ pub trait Platform<'data> { /// - elf_data: The raw bytes of the elf file. /// This must be the exact same elf file as the one the device was running. Even a recompilation of the exact same code can change the debug info. pub fn trace<'data, P: Platform<'data>>( + device_memory: DeviceMemory, + elf_data: &'data [u8], +) -> Result>, TraceError> +where + ::Bytes: bitvec::view::BitView, +{ + trace_inner::

(device_memory, elf_data, false) +} + +/// Like [`trace`], but skips collecting static variables. This is significantly +/// faster for large ELF files since it avoids walking all DWARF compilation units. +pub fn trace_no_statics<'data, P: Platform<'data>>( + device_memory: DeviceMemory, + elf_data: &'data [u8], +) -> Result>, TraceError> +where + ::Bytes: bitvec::view::BitView, +{ + trace_inner::

(device_memory, elf_data, true) +} + +fn trace_inner<'data, P: Platform<'data>>( mut device_memory: DeviceMemory, elf_data: &'data [u8], + skip_statics: bool, ) -> Result>, TraceError> where ::Bytes: bitvec::view::BitView, @@ -161,65 +185,40 @@ where } // We're done with the stack data, but we can also decode the static variables and make a frame out of that - let mut static_variables = - crate::variables::find_static_variables(&dwarf, &device_memory, &mut type_cache)?; - - // Filter out static variables that are not real (like defmt ones) - static_variables.retain(|var| { - let Some(linkage_name) = &var.linkage_name else { - // For some reason, some variables don't have a linkage name. - // So just show them, I guess? - return true; - }; + if !skip_statics { + // Build a symbol lookup HashMap once for O(1) early filtering inside + // find_static_variables, avoiding expensive type resolution for filtered-out vars. + let symbol_sections: HashMap<&str, Option> = elf + .symbols() + .filter_map(|sym| { + let name = sym.name().ok()?; + let section_kind = sym + .section_index() + .and_then(|idx| elf.section_by_index(idx).ok()) + .map(|section| section.kind()); + Some((name, section_kind)) + }) + .collect(); - if let Some(symbol) = elf.symbol_by_name(linkage_name) { - if let Some(section_index) = symbol.section_index() { - match elf.section_by_index(section_index) { - // Filter out all weird sections (including defmt) - Ok(section) if section.kind() == SectionKind::Other => false, - Ok(_section) => true, - Err(e) => { - log::error!("Could not get section by index: {e}"); - true - } - } - } else { - // The symbol is not defined in a section? - // Idk man, just show it I guess - true - } - } else { - // We have a linkage name from debug info, but the symbol doesn't exist... - // There's two things that might be going on that I know about: - // 1. LTO ran and removed the symbol because it was never used. - // 2. LLVM merged some globals (including this one) into one symbol. - // - // If 1, we want to return false. If 2, we want to return true. - - // For 1, if the variable has an address, it tends to be address 0 as far as I can see. - // This makes sense because it doesn't exist, and so doesn't have a 'real' address. - - if var.address.is_none() || var.address == Some(0) { - // We're likely in number 1 territory - false - } else { - // We _may_ be in number 2 territory - true - } - } - }); - - let static_frame = Frame { - function: "Static".into(), - location: Location { - file: None, - line: None, - column: None, - }, - frame_type: FrameType::Static, - variables: static_variables, - }; - frames.push(static_frame); + let static_variables = crate::variables::find_static_variables( + &dwarf, + &device_memory, + &mut type_cache, + Some(&symbol_sections), + )?; + + let static_frame = Frame { + function: "Static".into(), + location: Location { + file: None, + line: None, + column: None, + }, + frame_type: FrameType::Static, + variables: static_variables, + }; + frames.push(static_frame); + } // We're done Ok(frames) diff --git a/trace/src/variables/mod.rs b/trace/src/variables/mod.rs index dd6212b..1fc582a 100644 --- a/trace/src/variables/mod.rs +++ b/trace/src/variables/mod.rs @@ -1358,6 +1358,7 @@ pub fn find_static_variables( dwarf: &Dwarf, device_memory: &DeviceMemory, type_cache: &mut HashMap, TraceError>>, + symbol_filter: Option<&HashMap<&str, Option>>, ) -> Result>, TraceError> where ::Bytes: bitvec::view::BitView, @@ -1370,6 +1371,7 @@ where node: gimli::EntriesTreeNode, variables: &mut Vec>, type_cache: &mut HashMap, TraceError>>, + symbol_filter: Option<&HashMap<&str, Option>>, ) -> Result<(), TraceError> where ::Bytes: bitvec::view::BitView, @@ -1392,6 +1394,23 @@ where | gimli::constants::DW_TAG_union_type | gimli::constants::DW_TAG_volatile_type => return Ok(()), gimli::constants::DW_TAG_variable => { + // Early filter: check linkage name against symbol table + // BEFORE doing expensive type resolution + if let Some(filter) = symbol_filter { + let linkage_name = get_entry_linkage_name(dwarf, unit, entry)?; + if let Some(ln) = &linkage_name { + match filter.get(ln.as_str()) { + Some(Some(object::SectionKind::Other)) => return Ok(()), + Some(_) => {} // keep + None => { + // Symbol not in ELF — skip if no real address + // (can't check address without full resolution, so keep it) + return Ok(()); + } + } + } + } + if let Some(variable) = read_variable_entry( dwarf, unit, @@ -1424,6 +1443,7 @@ where child, variables, type_cache, + symbol_filter, )?; } @@ -1442,6 +1462,7 @@ where unit_header.entries_tree(&abbreviations, None)?.root()?, &mut variables, type_cache, + symbol_filter, )?; }