From 714b69b909ddd3ff51a29b403b26821abf2aa73d Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 4 May 2026 10:39:22 +0200 Subject: [PATCH 1/5] dep: Update goblin to 0.10.5 This is just the version bump part of #960. It also updates `scroll` to 0.13.0 to keep it in sync with `goblin`. This update requires a major bump because `goblin` types are publicly exported by `symbolic`. --- Cargo.lock | 32 ++++++++++++++++++++++++++------ Cargo.toml | 4 ++-- symbolic-debuginfo/src/pe.rs | 12 ++++++++---- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2fc7b4c40..1676b4b33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -812,13 +812,13 @@ dependencies = [ [[package]] name = "goblin" -version = "0.8.2" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" +checksum = "983a6aafb3b12d4c41ea78d39e189af4298ce747353945ff5105b54a056e5cd9" dependencies = [ "log", "plain", - "scroll 0.12.0", + "scroll 0.13.0", ] [[package]] @@ -2009,7 +2009,16 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" dependencies = [ - "scroll_derive", + "scroll_derive 0.12.0", +] + +[[package]] +name = "scroll" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1257cd4248b4132760d6524d6dda4e053bc648c9070b960929bf50cfb1e7add" +dependencies = [ + "scroll_derive 0.13.1", ] [[package]] @@ -2023,6 +2032,17 @@ dependencies = [ "syn", ] +[[package]] +name = "scroll_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed76efe62313ab6610570951494bdaa81568026e0318eaa55f167de70eeea67d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "semver" version = "1.0.24" @@ -2494,7 +2514,7 @@ dependencies = [ "pdb-addr2line", "proptest", "regex", - "scroll 0.12.0", + "scroll 0.13.0", "serde", "serde_json", "similar-asserts", @@ -2593,7 +2613,7 @@ dependencies = [ "flate2", "insta", "regex", - "scroll 0.12.0", + "scroll 0.13.0", "serde", "similar-asserts", "symbolic-testutils", diff --git a/Cargo.toml b/Cargo.toml index fe18021fa..70b3d6d14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ gimli = { version = "0.32.3", default-features = false, features = [ "std", "fallible-iterator", ] } -goblin = { version = "0.8.0", default-features = false } +goblin = { version = "0.10.5", default-features = false } indexmap = "2.0.0" insta = { version = "1.28.0", features = ["yaml"] } itertools = "0.14.0" @@ -49,7 +49,7 @@ proptest = "1.6.0" regex = "1.7.1" rustc-demangle = "0.1.21" # keep this in sync with whatever version `goblin` uses -scroll = "0.12.0" +scroll = "0.13.0" serde = { version = "1.0.171", features = ["derive"] } serde_json = "1.0.102" similar-asserts = "1.4.2" diff --git a/symbolic-debuginfo/src/pe.rs b/symbolic-debuginfo/src/pe.rs index e99cfcfbf..d5982bb1d 100644 --- a/symbolic-debuginfo/src/pe.rs +++ b/symbolic-debuginfo/src/pe.rs @@ -122,7 +122,11 @@ impl<'data> PeObject<'data> { debug_data .codeview_pdb70_debug_info .as_ref() - .map(|cv_record| (debug_data.image_debug_directory, cv_record)) + .map(|cv_record| { + let debug_directory = + debug_data.find_type(goblin::pe::debug::IMAGE_DEBUG_TYPE_CODEVIEW); + (debug_directory, cv_record) + }) }) .and_then(|(debug_directory, cv_record)| { let guid = &cv_record.signature; @@ -136,8 +140,8 @@ impl<'data> PeObject<'data> { // > Matching PDB ID is stored in the #Pdb stream of the .pdb file. // // See https://github.com/dotnet/runtime/blob/main/docs/design/specs/PE-COFF.md#codeview-debug-directory-entry-type-2 - let age = if debug_directory.minor_version == 0x504d { - debug_directory.time_date_stamp + let age = if let Some(d) = debug_directory.filter(|d| d.minor_version == 0x504d) { + d.time_date_stamp } else { cv_record.age }; @@ -191,7 +195,7 @@ impl<'data> PeObject<'data> { /// load address, so that the caller only has to deal with addresses relative to the actual /// start of the image. pub fn load_address(&self) -> u64 { - self.pe.image_base as u64 + self.pe.image_base } /// Determines whether this object exposes a public symbol table. From a90289b93f9b1195d708660e23635c45826c8e23 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 4 May 2026 11:17:15 +0200 Subject: [PATCH 2/5] Bump gimli --- Cargo.lock | 10 ++++---- Cargo.toml | 4 +-- symbolic-debuginfo/src/dwarf.rs | 43 +++++++++++++++++---------------- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1676b4b33..32871e349 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -802,9 +802,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "gimli" -version = "0.32.3" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" +checksum = "0bf7f043f89559805f8c7cacc432749b2fa0d0a0a9ee46ce47164ed5ba7f126c" dependencies = [ "fallible-iterator 0.3.0", "stable_deref_trait", @@ -2503,7 +2503,7 @@ dependencies = [ "elsa", "fallible-iterator 0.3.0", "flate2", - "gimli 0.32.3", + "gimli 0.33.0", "goblin", "insta", "memchr", @@ -2942,9 +2942,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.20.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "js-sys", "sha1_smol", diff --git a/Cargo.toml b/Cargo.toml index 70b3d6d14..51a53fa32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ fallible-iterator = "0.3.0" flate2 = { version = "1.1.8", default-features = false, features = [ "rust_backend", ] } -gimli = { version = "0.32.3", default-features = false, features = [ +gimli = { version = "0.33.0", default-features = false, features = [ "read", "std", "fallible-iterator", @@ -62,7 +62,7 @@ time = { version = "0.3.20", features = ["formatting"] } tokio = "1.36.0" tracing = "0.1.34" tracing-subscriber = "0.3.11" -uuid = "1.3.0" +uuid = "1.23.0" walkdir = "2.3.1" wasmparser = "0.243.0" watto = { version = "0.2.0", features = ["writer", "strings"] } diff --git a/symbolic-debuginfo/src/dwarf.rs b/symbolic-debuginfo/src/dwarf.rs index 35f755971..951d94e14 100644 --- a/symbolic-debuginfo/src/dwarf.rs +++ b/symbolic-debuginfo/src/dwarf.rs @@ -55,11 +55,11 @@ type RangeLists<'a> = gimli::read::RangeLists>; type Unit<'a> = gimli::read::Unit>; type DwarfInner<'a> = gimli::read::Dwarf>; -type Die<'d, 'u> = gimli::read::DebuggingInformationEntry<'u, 'u, Slice<'d>, usize>; +type Die<'d, 'u> = gimli::read::DebuggingInformationEntry, usize>; type Attribute<'a> = gimli::read::Attribute>; type UnitOffset = gimli::read::UnitOffset; type DebugInfoOffset = gimli::DebugInfoOffset; -type EntriesRaw<'d, 'u> = gimli::EntriesRaw<'u, 'u, Slice<'d>>; +type EntriesRaw<'d, 'u> = gimli::EntriesRaw<'u, Slice<'d>>; type UnitHeader<'a> = gimli::read::UnitHeader>; type IncompleteLineNumberProgram<'a> = gimli::read::IncompleteLineProgram>; @@ -416,11 +416,10 @@ impl<'d> UnitRef<'d, '_> { /// Returns the source language declared in the root DIE of this compilation unit. fn language(&self) -> Result, DwarfError> { let mut entries = self.unit.entries(); - let Some((_, root_entry)) = entries.next_dfs()? else { + let Some(root_entry) = entries.next_dfs()? else { return Ok(None); }; - let Some(AttributeValue::Language(lang)) = - root_entry.attr_value(constants::DW_AT_language)? + let Some(AttributeValue::Language(lang)) = root_entry.attr_value(constants::DW_AT_language) else { return Ok(None); }; @@ -442,8 +441,8 @@ impl<'d> UnitRef<'d, '_> { if depth == 0 { return Ok(None); } - if let Ok(Some(attr)) = entry.attr(constants::DW_AT_abstract_origin) { - return self.resolve_reference(attr, |ref_unit, ref_entry| { + if let Some(attr) = entry.attr(constants::DW_AT_abstract_origin) { + return self.resolve_reference(*attr, |ref_unit, ref_entry| { // Recurse first to follow deeper chains. if let Some(lang) = ref_unit.resolve_entry_language(ref_entry, depth - 1)? { return Ok(Some(lang)); @@ -467,11 +466,10 @@ impl<'d> UnitRef<'d, '_> { bcsymbolmap: Option<&'d BcSymbolMap<'d>>, prior_offset: Option, ) -> Result>, DwarfError> { - let mut attrs = entry.attrs(); let mut fallback_name = None; let mut reference_target = None; - while let Some(attr) = attrs.next()? { + for attr in entry.attrs() { match attr.name() { // Prioritize these. If we get them, take them. constants::DW_AT_linkage_name | constants::DW_AT_MIPS_linkage_name => { @@ -498,7 +496,7 @@ impl<'d> UnitRef<'d, '_> { } if let Some(attr) = reference_target { - return self.resolve_reference(attr, |ref_unit, ref_entry| { + return self.resolve_reference(*attr, |ref_unit, ref_entry| { // Self-references may have a layer of indirection. Avoid infinite recursion // in this scenario. if let Some(prior) = prior_offset { @@ -544,7 +542,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> { let inner = UnitRef { info, unit }; let mut entries = unit.entries(); let entry = match entries.next_dfs()? { - Some((_, entry)) => entry, + Some(entry) => entry, None => return Err(gimli::read::Error::MissingUnitDie.into()), }; @@ -554,12 +552,12 @@ impl<'d, 'a> DwarfUnit<'d, 'a> { // range information has not been written yet and all units look like this. if info.kind != ObjectKind::Relocatable && unit.low_pc == 0 - && entry.attr(constants::DW_AT_ranges)?.is_none() + && entry.attr(constants::DW_AT_ranges).is_none() { return Ok(None); } - let language = match entry.attr_value(constants::DW_AT_language)? { + let language = match entry.attr_value(constants::DW_AT_language) { Some(AttributeValue::Language(lang)) => language_from_dwarf(lang), _ => Language::Unknown, }; @@ -573,7 +571,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> { // reference into the debug_str section. We use `string_value` // to resolve it correctly in either case. let producer = entry - .attr_value(constants::DW_AT_producer)? + .attr_value(constants::DW_AT_producer) .and_then(|av| av.string_value(&info.inner.debug_str)); // Trust the symbol table more to contain accurate mangled names. However, since Dart's name @@ -626,7 +624,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> { AttributeValue::DebugAddrIndex(index) => { low_pc = Some(self.inner.info.address(self.inner.unit, index)?) } - _ => return Err(GimliError::UnsupportedAttributeForm.into()), + _ => return Err(GimliError::UnsupportedAttributeForm(attr.form()).into()), }, constants::DW_AT_high_pc => match attr.value() { AttributeValue::Addr(addr) => high_pc = Some(addr), @@ -634,15 +632,15 @@ impl<'d, 'a> DwarfUnit<'d, 'a> { high_pc = Some(self.inner.info.address(self.inner.unit, index)?) } AttributeValue::Udata(size) => high_pc_rel = Some(size), - _ => return Err(GimliError::UnsupportedAttributeForm.into()), + _ => return Err(GimliError::UnsupportedAttributeForm(attr.form()).into()), }, constants::DW_AT_call_line => match attr.value() { AttributeValue::Udata(line) => call_line = Some(line), - _ => return Err(GimliError::UnsupportedAttributeForm.into()), + _ => return Err(GimliError::UnsupportedAttributeForm(attr.form()).into()), }, constants::DW_AT_call_file => match attr.value() { AttributeValue::FileIndex(file) => call_file = Some(file), - _ => return Err(GimliError::UnsupportedAttributeForm.into()), + _ => return Err(GimliError::UnsupportedAttributeForm(attr.form()).into()), }, constants::DW_AT_ranges | constants::DW_AT_rnglists_base @@ -656,7 +654,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> { // are triggered by an inverted range (going high to low). // See a few more examples of broken ranges here: // https://github.com/emscripten-core/emscripten/issues/15552 - Err(gimli::Error::InvalidAddressRange) => None, + Err(gimli::Error::InvalidCfiSetLoc(_)) => None, Err(err) => { return Err(err.into()); } @@ -1175,6 +1173,7 @@ struct DwarfSections<'data> { debug_info: DwarfSectionData<'data, gimli::read::DebugInfo>>, debug_line: DwarfSectionData<'data, gimli::read::DebugLine>>, debug_line_str: DwarfSectionData<'data, gimli::read::DebugLineStr>>, + debug_names: DwarfSectionData<'data, gimli::read::DebugNames>>, debug_str: DwarfSectionData<'data, gimli::read::DebugStr>>, debug_str_offsets: DwarfSectionData<'data, gimli::read::DebugStrOffsets>>, debug_ranges: DwarfSectionData<'data, gimli::read::DebugRanges>>, @@ -1196,6 +1195,7 @@ impl<'data> DwarfSections<'data> { debug_info: DwarfSectionData::load(dwarf), debug_line: DwarfSectionData::load(dwarf), debug_line_str: DwarfSectionData::load(dwarf), + debug_names: DwarfSectionData::load(dwarf), debug_str: DwarfSectionData::load(dwarf), debug_str_offsets: DwarfSectionData::load(dwarf), debug_ranges: DwarfSectionData::load(dwarf), @@ -1239,6 +1239,7 @@ impl<'d> DwarfInfo<'d> { debug_info: sections.debug_info.to_gimli(), debug_line: sections.debug_line.to_gimli(), debug_line_str: sections.debug_line_str.to_gimli(), + debug_names: sections.debug_names.to_gimli(), debug_str: sections.debug_str.to_gimli(), debug_str_offsets: sections.debug_str_offsets.to_gimli(), debug_types: Default::default(), @@ -1255,7 +1256,7 @@ impl<'d> DwarfInfo<'d> { inner.populate_abbreviations_cache(AbbreviationsCacheStrategy::Duplicates); // Prepare random access to unit headers. - let headers = inner.units().collect::>()?; + let headers = FallibleIterator::collect::>(inner.units())?; let units = headers.iter().map(|_| OnceCell::new()).collect(); Ok(DwarfInfo { @@ -1297,7 +1298,7 @@ impl<'d> DwarfInfo<'d> { &self, offset: DebugInfoOffset, ) -> Result<(UnitRef<'d, '_>, UnitOffset), DwarfError> { - let section_offset = UnitSectionOffset::DebugInfoOffset(offset); + let section_offset = UnitSectionOffset(offset.0); let search_result = self .headers .binary_search_by_key(§ion_offset, UnitHeader::offset); From bd75def0ece12484356c71ce8532842dfba9a4d6 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 4 May 2026 12:39:12 +0200 Subject: [PATCH 3/5] Remove unnecessary lifetime --- symbolic-debuginfo/src/dwarf.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/symbolic-debuginfo/src/dwarf.rs b/symbolic-debuginfo/src/dwarf.rs index 951d94e14..0201e0c48 100644 --- a/symbolic-debuginfo/src/dwarf.rs +++ b/symbolic-debuginfo/src/dwarf.rs @@ -55,7 +55,7 @@ type RangeLists<'a> = gimli::read::RangeLists>; type Unit<'a> = gimli::read::Unit>; type DwarfInner<'a> = gimli::read::Dwarf>; -type Die<'d, 'u> = gimli::read::DebuggingInformationEntry, usize>; +type Die<'d> = gimli::read::DebuggingInformationEntry, usize>; type Attribute<'a> = gimli::read::Attribute>; type UnitOffset = gimli::read::UnitOffset; type DebugInfoOffset = gimli::DebugInfoOffset; @@ -389,7 +389,7 @@ impl<'d> UnitRef<'d, '_> { /// abbrev can only be temporarily accessed in the callback. fn resolve_reference(&self, attr: Attribute<'d>, f: F) -> Result, DwarfError> where - F: FnOnce(Self, &Die<'d, '_>) -> Result, DwarfError>, + F: FnOnce(Self, &Die<'d>) -> Result, DwarfError>, { let (unit, offset) = match attr.value() { AttributeValue::UnitRef(offset) => (*self, offset), @@ -435,7 +435,7 @@ impl<'d> UnitRef<'d, '_> { /// cycles or malformed DWARF. fn resolve_entry_language( &self, - entry: &Die<'d, '_>, + entry: &Die<'d>, depth: u8, ) -> Result, DwarfError> { if depth == 0 { @@ -461,7 +461,7 @@ impl<'d> UnitRef<'d, '_> { /// Resolves the function name of a debug entry. fn resolve_function_name( &self, - entry: &Die<'d, '_>, + entry: &Die<'d>, language: Language, bcsymbolmap: Option<&'d BcSymbolMap<'d>>, prior_offset: Option, @@ -776,11 +776,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> { /// does not reflect the original source language (e.g., a C++ CU containing functions /// originally written in C). When such a CU's subprogram carries a cross-unit /// `DW_AT_abstract_origin`, the referenced CU's language is more authoritative. - fn resolve_function_language( - &self, - entry: &Die<'d, '_>, - fallback_language: Language, - ) -> Language { + fn resolve_function_language(&self, entry: &Die<'d>, fallback_language: Language) -> Language { self.inner .resolve_entry_language(entry, UnitRef::MAX_ABSTRACT_ORIGIN_DEPTH) .ok() From 8eafb0710d8ce3f19b2b0f76712895c3e8948294 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 4 May 2026 12:41:45 +0200 Subject: [PATCH 4/5] Changelog --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e0f2d3d9..943838516 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## Unreleased + +### Dependencies + +- Update several publicly exposed dependencies: + - `gimli`: 0.32.3 -> 0.33.0 + - `goblin`: 0.8.0 -> 0.10.5 + - `scroll`: 0.12.0 -> 0.13.0 + - `uuid`: 1.3.0 -> 1.23.0 + ([#976](https://github.com/getsentry/symbolic/pull/976)) + ## 12.18.3 ### Internal Changes 🔧 From 21ed7a81b4d7f5ba403debe8cc185947d61d0cb8 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 4 May 2026 12:51:23 +0200 Subject: [PATCH 5/5] Don't update uuid --- CHANGELOG.md | 3 +-- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 243406986..af5f0aee5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,14 +6,13 @@ - Extract srcsrv data from PDB for file mapping by @mujajica and @loewenheim. This includes a bump of the SymCache format to version 9. ([#943](https://github.com/getsentry/symbolic/pull/943)) - + **Dependencies** - Update several publicly exposed dependencies: - `gimli`: 0.32.3 -> 0.33.0 - `goblin`: 0.8.0 -> 0.10.5 - `scroll`: 0.12.0 -> 0.13.0 - - `uuid`: 1.3.0 -> 1.23.0 ([#976](https://github.com/getsentry/symbolic/pull/976)) ## 12.18.3 diff --git a/Cargo.lock b/Cargo.lock index 32871e349..5235cf4d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2942,9 +2942,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ "js-sys", "sha1_smol", diff --git a/Cargo.toml b/Cargo.toml index 51a53fa32..fb7473717 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,7 +62,7 @@ time = { version = "0.3.20", features = ["formatting"] } tokio = "1.36.0" tracing = "0.1.34" tracing-subscriber = "0.3.11" -uuid = "1.23.0" +uuid = "1.3.0" walkdir = "2.3.1" wasmparser = "0.243.0" watto = { version = "0.2.0", features = ["writer", "strings"] }