Skip to content

Commit

Permalink
First attempt at macos.
Browse files Browse the repository at this point in the history
  • Loading branch information
afranchuk committed Jan 18, 2024
1 parent 16bbce8 commit aff54e2
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 44 deletions.
19 changes: 10 additions & 9 deletions samply/src/mac/proc_maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub struct DyldInfo {
pub file: String,
pub base_avma: u64,
pub vmsize: u64,
pub svma_info: framehop::ModuleSvmaInfo,
pub module_info: framehop::ExplicitModuleSectionInfo<UnwindSectionBytes>,
pub debug_id: Option<DebugId>,
pub code_id: Option<CodeId>,
pub arch: Option<&'static str>,
Expand Down Expand Up @@ -309,15 +309,15 @@ fn get_dyld_image_info(
file: filename,
base_avma,
vmsize,
svma_info: framehop::ModuleSvmaInfo {
module_info: framehop::ExplicitModuleSectionInfo {
base_svma,
text: section_svma_range(b"__text"),
text_env: section_svma_range(b"text_env"),
stubs: section_svma_range(b"__stubs"),
stub_helper: section_svma_range(b"__stub_helper"),
eh_frame: section_svma_range(b"__eh_frame"),
eh_frame_hdr: section_svma_range(b"__eh_frame_hdr"),
got: section_svma_range(b"__got"),
text_svma: section_svma_range(b"__text"),
stubs_svma: section_svma_range(b"__stubs"),
stub_helper_svma: section_svma_range(b"__stub_helper"),
eh_frame_svma: section_svma_range(b"__eh_frame"),
eh_frame_hdr_svma: section_svma_range(b"__eh_frame_hdr"),
got_svma: section_svma_range(b"__got"),
..Default::default()
},
debug_id: uuid.map(DebugId::from_uuid),
code_id: uuid.map(CodeId::MachoUuid),
Expand Down Expand Up @@ -617,6 +617,7 @@ impl ForeignMemory {
}
}

#[derive(Clone)]
pub struct VmSubData {
page_aligned_data: VmData,
address_range: std::ops::Range<u64>,
Expand Down
64 changes: 29 additions & 35 deletions samply/src/mac/task_profiler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crossbeam_channel::Receiver;
use framehop::{
CacheNative, FrameAddress, MayAllocateDuringUnwind, Module, ModuleUnwindData, TextByteData,
CacheNative, ExplicitModuleSectionInfo, FrameAddress, MayAllocateDuringUnwind, Module,
Unwinder, UnwinderNative,
};
use fxprof_processed_profile::debugid::DebugId;
Expand All @@ -22,6 +22,7 @@ use std::collections::{HashMap, HashSet};
use std::mem;
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::sync::Arc;

use crate::shared::jit_category_manager::JitCategoryManager;
use crate::shared::jit_function_recycler::JitFunctionRecycler;
Expand All @@ -41,10 +42,11 @@ use super::proc_maps::{DyldInfo, DyldInfoManager, Modification, StackwalkerRef,
use super::sampler::TaskInit;
use super::thread_profiler::{get_thread_id, get_thread_name, ThreadProfiler};

#[derive(Clone)]
pub enum UnwindSectionBytes {
Remapped(VmSubData),
Mmap(MmapSubData),
Allocated(Vec<u8>),
Allocated(Arc<[u8]>),
}

impl Deref for UnwindSectionBytes {
Expand All @@ -54,7 +56,7 @@ impl Deref for UnwindSectionBytes {
match self {
UnwindSectionBytes::Remapped(vm_sub_data) => vm_sub_data.deref(),
UnwindSectionBytes::Mmap(mmap_sub_data) => mmap_sub_data.deref(),
UnwindSectionBytes::Allocated(vec) => vec.deref(),
UnwindSectionBytes::Allocated(data) => data.deref(),
}
}
}
Expand Down Expand Up @@ -431,7 +433,8 @@ impl TaskProfiler {
}

fn add_lib_to_unwinder_and_ensure_debug_id(&mut self, lib: &mut DyldInfo) {
let base_svma = lib.svma_info.base_svma;
let mut module_section_info = lib.module_info.clone();
let base_svma = module_section_info.base_svma;
let base_avma = lib.base_avma;
let unwind_info_data = lib
.unwind_sections
Expand All @@ -445,23 +448,23 @@ impl TaskProfiler {
.and_then(|(svma, size)| {
VmSubData::map_from_task(self.task, svma - base_svma + base_avma, size).ok()
});
let text_data = lib.unwind_sections.text_segment.and_then(|(svma, size)| {
let text_segment = lib.unwind_sections.text_segment.and_then(|(svma, size)| {
let avma = svma - base_svma + base_avma;
VmSubData::map_from_task(self.task, avma, size)
.ok()
.map(|data| {
TextByteData::new(UnwindSectionBytes::Remapped(data), avma..avma + size)
})
.map(|data| (UnwindSectionBytes::Remapped(data), avma..avma + size))
});

if lib.debug_id.is_none() {
if let (Some(text_data), Some(text_section)) =
(text_data.as_ref(), lib.svma_info.text.clone())
if let (Some((text_segment, text_segment_avma)), Some(text_section)) =
(text_segment.as_ref(), lib.module_info.text_svma.clone())
{
let text_section_start_avma = text_section.start - base_svma + base_avma;
let text_section_first_page_end_avma = text_section_start_avma.wrapping_add(4096);
let debug_id = if let Some(text_first_page) =
text_data.get_bytes(text_section_start_avma..text_section_first_page_end_avma)
let debug_id = if let Some(text_first_page) = text_section_start_avma
.checked_sub(text_segment_avma.start)
.zip(text_section_first_page_end_avma.checked_sub(text_segment_avma.start))
.and_then(|(rel_start, rel_end)| text_segment.get(rel_start..rel_end))
{
// Generate a debug ID from the __text section.
DebugId::from_text_first_page(text_first_page, true)
Expand All @@ -471,33 +474,24 @@ impl TaskProfiler {
lib.debug_id = Some(debug_id);
}
}

let unwind_data = match (unwind_info_data, eh_frame_data) {
(Some(unwind_info), eh_frame) => ModuleUnwindData::CompactUnwindInfoAndEhFrame(
UnwindSectionBytes::Remapped(unwind_info),
eh_frame.map(UnwindSectionBytes::Remapped),
),
(None, Some(eh_frame)) => {
ModuleUnwindData::EhFrame(UnwindSectionBytes::Remapped(eh_frame))
}
(None, None) => {
// Have no unwind information.
// Let's try to open the file and use debug_frame.
if let Some(debug_frame) = get_debug_frame(&lib.file) {
ModuleUnwindData::DebugFrame(debug_frame)
} else {
ModuleUnwindData::None
}
}
};
let (text_segment, text_segment_file_range) = text_segment.unzip();

module_section_info.text_segment_file_range = text_segment_file_range;
module_section_info.text_segment = text_segment.clone();
module_section_info.text = text_segment;
module_section_info.unwind_info = unwind_info_data.map(UnwindSectionBytes::Remapped);
module_section_info.eh_frame = eh_frame_data.map(UnwindSectionBytes::Remapped);
if module_section_info.unwind_info.is_none() && module_section_info.eh_frame.is_none() {
// We have no unwind information.
// Let's try to open the file and use debug_frame.
module_section_info.debug_frame = get_debug_frame(&lib.file);
}

let module = Module::new(
lib.file.clone(),
lib.base_avma..(lib.base_avma + lib.vmsize),
lib.base_avma,
lib.svma_info.clone(),
unwind_data,
text_data,
module_section_info,
);
self.unwinder.add_module(module);
}
Expand Down Expand Up @@ -628,7 +622,7 @@ fn get_debug_frame(file_path: &str) -> Option<UnwindSectionBytes> {
flate2::FlushDecompress::Finish,
)
.ok()?;
Some(UnwindSectionBytes::Allocated(decompressed))
Some(UnwindSectionBytes::Allocated(decompressed.into()))
}
_ => None,
}
Expand Down

0 comments on commit aff54e2

Please sign in to comment.