| 303 | } |
| 304 | |
| 305 | fn lookup_frames<'a>( |
| 306 | modules: &'a Modules, |
| 307 | backtrace: &'a Backtrace, |
| 308 | ) -> impl Iterator<Item = FrameInfo> + 'a { |
| 309 | backtrace |
| 310 | .frames() |
| 311 | // Samply needs to see the oldest frame first, but we list the newest |
| 312 | // first, so iterate in reverse. |
| 313 | .rev() |
| 314 | .filter_map(|frame| { |
| 315 | let idx = modules |
| 316 | .binary_search_by(|probe| { |
| 317 | if probe.text_range.contains(&frame.pc()) { |
| 318 | Ordering::Equal |
| 319 | } else { |
| 320 | probe.text_range.start.cmp(&frame.pc()) |
| 321 | } |
| 322 | }) |
| 323 | .ok()?; |
| 324 | let module = modules.get(idx)?; |
| 325 | |
| 326 | // We need to point to the modules full text (not just its functions) as |
| 327 | // the offset for the final phase; these can be different for component |
| 328 | // model modules. |
| 329 | let module_text_start = module.module.text().as_ptr_range().start as usize; |
| 330 | return Some(FrameInfo { |
| 331 | frame: Frame::RelativeAddressFromReturnAddress( |
| 332 | module.fxprof_libhandle, |
| 333 | u32::try_from(frame.pc() - module_text_start).unwrap(), |
| 334 | ), |
| 335 | category_pair: CategoryHandle::OTHER.into(), |
| 336 | flags: FrameFlags::empty(), |
| 337 | }); |
| 338 | }) |
| 339 | } |
| 340 | |
| 341 | #[derive(Debug, Clone, Copy)] |
| 342 | struct CallMarker { |