diff --git a/src/lib.rs b/src/lib.rs index ac94e5b..c678310 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -521,7 +521,9 @@ fn demangle_stream(input: &mut R, output: &mut W) -> std:: let mangled = String::from_utf8_lossy(attr.value.as_ref()); if let Ok(demangled) = try_demangle(&mangled) { - let demangled = format!("{demangled:#}"); + // Folded stacks use semicolons as frame separators. Keep semicolons that + // occur inside Rust array types from being interpreted as extra frames. + let demangled = format!("{demangled:#}").replace(';', ":"); attr.value = match quick_xml::escape::escape(demangled) { Cow::Borrowed(s) => Cow::Borrowed(s.as_bytes()), Cow::Owned(s) => Cow::Owned(s.into_bytes()), @@ -818,3 +820,24 @@ impl FlamegraphOptions { options } } + +#[cfg(all(test, target_os = "macos"))] +mod tests { + use std::io::Cursor; + + use super::demangle_stream; + + #[test] + fn keeps_array_types_inside_one_folded_frame() { + let mut input = + Cursor::new(br#""#); + let mut output = Vec::new(); + + demangle_stream(&mut input, &mut output).unwrap(); + + assert_eq!( + String::from_utf8(output).unwrap(), + r#""# + ); + } +}