Backtrace WebAssembly function JIT frames (#759)

* Create backtrace

* Extend unwind information with FDE data.

* Expose backtrace via API/Trap

* wasmtime_call returns not-str

* Return Arc<JITFrameTag>

* rename frame -> function

* Fix windows crashes and unwrap UNWIND_HISTORY_TABLE

* mmaps -> entries

* pass a backtrace in ActionOutcome

* add test_trap_stack_overflow

* Update cranelift version.
This commit is contained in:
Yury Delendik
2020-01-15 13:48:24 -06:00
committed by GitHub
parent 0848a7eaaa
commit 2a50701f0a
26 changed files with 803 additions and 149 deletions

View File

@@ -16,12 +16,12 @@ use wasmtime_environ::entity::{EntityRef, PrimaryMap};
use wasmtime_environ::isa::{TargetFrontendConfig, TargetIsa};
use wasmtime_environ::wasm::{DefinedFuncIndex, DefinedMemoryIndex};
use wasmtime_environ::{
Compilation, CompileError, CompiledFunction, Compiler as _C, FunctionBodyData, Module,
ModuleVmctxInfo, Relocations, Traps, Tunables, VMOffsets,
Compilation, CompileError, CompiledFunction, CompiledFunctionUnwindInfo, Compiler as _C,
FunctionBodyData, Module, ModuleVmctxInfo, Relocations, Traps, Tunables, VMOffsets,
};
use wasmtime_runtime::{
get_mut_trap_registry, InstantiationError, SignatureRegistry, TrapRegistrationGuard,
VMFunctionBody,
get_mut_trap_registry, jit_function_registry, InstantiationError, SignatureRegistry,
TrapRegistrationGuard, VMFunctionBody,
};
/// Select which kind of compilation to use.
@@ -51,6 +51,7 @@ pub struct Compiler {
code_memory: CodeMemory,
trap_registration_guards: Vec<TrapRegistrationGuard>,
jit_function_ranges: Vec<(usize, usize)>,
trampoline_park: HashMap<*const VMFunctionBody, *const VMFunctionBody>,
signatures: SignatureRegistry,
strategy: CompilationStrategy,
@@ -66,6 +67,7 @@ impl Compiler {
isa,
code_memory: CodeMemory::new(),
trap_registration_guards: Vec::new(),
jit_function_ranges: Vec::new(),
trampoline_park: HashMap::new(),
signatures: SignatureRegistry::new(),
fn_builder_ctx: FunctionBuilderContext::new(),
@@ -85,6 +87,10 @@ impl Drop for Compiler {
// Having a custom drop implementation we are independent from the field order
// in the struct what reduces potential human error.
self.trap_registration_guards.clear();
for (start, end) in self.jit_function_ranges.iter() {
jit_function_registry::unregister(*start, *end);
}
}
}
@@ -155,6 +161,18 @@ impl Compiler {
&mut self.trap_registration_guards,
);
for (i, allocated) in allocated_functions.iter() {
let ptr = (*allocated) as *const VMFunctionBody;
let body_len = compilation.get(i).body.len();
self.jit_function_ranges
.push((ptr as usize, ptr as usize + body_len));
let tag = jit_function_registry::JITFunctionTag {
module_id: module.name.clone(),
func_index: i.index(),
};
jit_function_registry::register(ptr as usize, ptr as usize + body_len, tag);
}
let dbg = if let Some(debug_data) = debug_data {
let target_config = self.isa.frontend_config();
let ofs = VMOffsets::new(target_config.pointer_bytes(), &module);
@@ -215,6 +233,7 @@ impl Compiler {
signature,
value_size,
)?;
entry.insert(body);
body
}
@@ -266,6 +285,7 @@ fn make_trampoline(
let mut context = Context::new();
context.func = ir::Function::with_name_signature(ir::ExternalName::user(0, 0), wrapper_sig);
context.func.collect_frame_layout_info();
{
let mut builder = FunctionBuilder::new(&mut context.func, fn_builder_ctx);
@@ -326,7 +346,6 @@ fn make_trampoline(
}
let mut code_buf = Vec::new();
let mut unwind_info = Vec::new();
let mut reloc_sink = RelocSink {};
let mut trap_sink = binemit::NullTrapSink {};
let mut stackmap_sink = binemit::NullStackmapSink {};
@@ -346,7 +365,7 @@ fn make_trampoline(
)))
})?;
context.emit_unwind_info(isa, &mut unwind_info);
let unwind_info = CompiledFunctionUnwindInfo::new(isa, &context);
Ok(code_memory
.allocate_for_function(&CompiledFunction {