Support vtune profiling of trampolines too (#3687)

* Provide helpers for demangling function names

* Profile trampolines in vtune too

* get rid of mapping

* avoid code duplication with jitdump_linux

* maintain previous default display name for wasm functions

* no dash, grrr

* Remove unused profiling error type
This commit is contained in:
Benjamin Bouvier
2022-01-19 16:49:23 +01:00
committed by GitHub
parent 2afd6900f4
commit 2649d2352c
13 changed files with 191 additions and 141 deletions

View File

@@ -26,8 +26,6 @@ region = "2.2.0"
libc = "0.2"
cfg-if = "1.0"
backtrace = "0.3.61"
rustc-demangle = "0.1.16"
cpp_demangle = "0.3.2"
log = "0.4.8"
wat = { version = "1.0.36", optional = true }
serde = { version = "1.0.94", features = ["derive"] }

View File

@@ -6,7 +6,7 @@ use std::any::Any;
use std::panic::{self, AssertUnwindSafe};
use std::sync::Arc;
use wasmtime_environ::{EntityIndex, Module, ModuleType, PrimaryMap, SignatureIndex};
use wasmtime_jit::{CodeMemory, MmapVec};
use wasmtime_jit::{CodeMemory, MmapVec, ProfilingAgent};
use wasmtime_runtime::{
Imports, InstanceAllocationRequest, InstanceAllocator, InstanceHandle,
OnDemandInstanceAllocator, StorePtr, VMContext, VMFunctionBody, VMSharedSignatureIndex,
@@ -66,6 +66,39 @@ unsafe extern "C" fn stub_fn<F>(
}
}
#[cfg(compiler)]
fn register_trampolines(profiler: &dyn ProfilingAgent, image: &object::File<'_>) {
use object::{Object as _, ObjectSection, ObjectSymbol, SectionKind, SymbolKind};
let pid = std::process::id();
let tid = pid;
let text_base = match image.sections().find(|s| s.kind() == SectionKind::Text) {
Some(section) => match section.data() {
Ok(data) => data.as_ptr() as usize,
Err(_) => return,
},
None => return,
};
for sym in image.symbols() {
if !sym.is_definition() {
continue;
}
if sym.kind() != SymbolKind::Text {
continue;
}
let address = sym.address();
let size = sym.size();
if address == 0 || size == 0 {
continue;
}
if let Ok(name) = sym.name() {
let addr = text_base + address as usize;
profiler.load_single_trampoline(name, addr as *const u8, size as usize, pid, tid);
}
}
}
#[cfg(compiler)]
pub fn create_function<F>(
ft: &FuncType,
@@ -87,7 +120,8 @@ where
// also take care of unwind table registration.
let mut code_memory = CodeMemory::new(obj);
let code = code_memory.publish()?;
engine.config().profiler.trampoline_load(&code.obj);
register_trampolines(engine.config().profiler.as_ref(), &code.obj);
// Extract the host/wasm trampolines from the results of compilation since
// we know their start/length.

View File

@@ -4,6 +4,7 @@ use backtrace::Backtrace;
use std::fmt;
use std::sync::Arc;
use wasmtime_environ::TrapCode as EnvTrapCode;
use wasmtime_jit::{demangle_function_name, demangle_function_name_or_index};
/// A struct representing an aborted instruction execution, with a message
/// indicating the cause.
@@ -327,17 +328,8 @@ impl fmt::Display for Trap {
write!(f, "{:#6x} - ", offset)?;
}
let demangle =
|f: &mut fmt::Formatter<'_>, name: &str| match rustc_demangle::try_demangle(name) {
Ok(name) => write!(f, "{}", name),
Err(_) => match cpp_demangle::Symbol::new(name) {
Ok(name) => write!(f, "{}", name),
Err(_) => write!(f, "{}", name),
},
};
let write_raw_func_name = |f: &mut fmt::Formatter<'_>| match frame.func_name() {
Some(name) => demangle(f, name),
None => write!(f, "<wasm function {}>", frame.func_index()),
let write_raw_func_name = |f: &mut fmt::Formatter<'_>| {
demangle_function_name_or_index(f, frame.func_name(), frame.func_index() as usize)
};
if frame.symbols().is_empty() {
write!(f, "{}!", name)?;
@@ -351,7 +343,7 @@ impl fmt::Display for Trap {
// ...
}
match symbol.name() {
Some(name) => demangle(f, name)?,
Some(name) => demangle_function_name(f, name)?,
None if i == 0 => write_raw_func_name(f)?,
None => write!(f, "<inlined function>")?,
}