wasmtime/profiling_agent/
jitdump.rs1use crate::prelude::*;
15use crate::profiling_agent::ProfilingAgent;
16use object::elf;
17use std::process;
18use std::sync::Mutex;
19use target_lexicon::Architecture;
20use wasmtime_jit_debug::perf_jitdump::*;
21
22struct JitDumpAgent {
24 pid: u32,
25}
26
27static JITDUMP_FILE: Mutex<Option<JitDumpFile>> = Mutex::new(None);
29
30pub fn new() -> Result<Box<dyn ProfilingAgent>> {
32 let mut jitdump_file = JITDUMP_FILE.lock().unwrap();
33
34 if jitdump_file.is_none() {
35 let filename = format!("./jit-{}.dump", process::id());
36 let e_machine = match target_lexicon::HOST.architecture {
37 Architecture::X86_64 => elf::EM_X86_64 as u32,
38 Architecture::X86_32(_) => elf::EM_386 as u32,
39 Architecture::Arm(_) => elf::EM_ARM as u32,
40 Architecture::Aarch64(_) => elf::EM_AARCH64 as u32,
41 Architecture::S390x => elf::EM_S390 as u32,
42 _ => unimplemented!("unrecognized architecture"),
43 };
44 *jitdump_file = Some(JitDumpFile::new(filename, e_machine)?);
45 }
46
47 Ok(Box::new(JitDumpAgent {
48 pid: std::process::id(),
49 }))
50}
51
52impl ProfilingAgent for JitDumpAgent {
53 fn register_function(&self, name: &str, code: &[u8]) {
54 let mut jitdump_file = JITDUMP_FILE.lock().unwrap();
55 let jitdump_file = jitdump_file.as_mut().unwrap();
56 let timestamp = jitdump_file.get_time_stamp();
57 #[allow(trivial_numeric_casts)]
58 let tid = rustix::thread::gettid().as_raw_nonzero().get() as u32;
59 if let Err(err) = jitdump_file.dump_code_load_record(&name, code, timestamp, self.pid, tid)
60 {
61 println!("Jitdump: write_code_load_failed_record failed: {err:?}\n");
62 }
63 }
64}