From b0b0983eb8e27a1fae1e46764e3e97b283787ded Mon Sep 17 00:00:00 2001 From: losfair Date: Sun, 13 Oct 2019 20:51:39 +0800 Subject: [PATCH] Allow accessing execution state in middleware breakpoint handlers. --- lib/runtime-core/src/codegen.rs | 3 ++- lib/runtime-core/src/fault.rs | 36 ++++++++++++++++++++++----------- lib/runtime-core/src/state.rs | 13 +++++++++--- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/lib/runtime-core/src/codegen.rs b/lib/runtime-core/src/codegen.rs index e69b9637c..46534fac1 100644 --- a/lib/runtime-core/src/codegen.rs +++ b/lib/runtime-core/src/codegen.rs @@ -3,6 +3,7 @@ use crate::{ backend::{Backend, CacheGen, Compiler, CompilerConfig, Features, Token}, cache::{Artifact, Error as CacheError}, error::{CompileError, CompileResult}, + fault::FaultInfo, module::{ModuleInfo, ModuleInner}, structures::Map, types::{FuncIndex, FuncSig, SigIndex}, @@ -49,7 +50,7 @@ impl fmt::Debug for InternalEvent { } pub struct BreakpointInfo<'a> { - pub fault: Option<&'a dyn Any>, + pub fault: Option<&'a FaultInfo>, } pub trait ModuleCodeGenerator, RM: RunnableModule, E: Debug> { diff --git a/lib/runtime-core/src/fault.rs b/lib/runtime-core/src/fault.rs index 51d00d52e..ae0bf65c9 100644 --- a/lib/runtime-core/src/fault.rs +++ b/lib/runtime-core/src/fault.rs @@ -20,7 +20,7 @@ pub mod raw { use crate::codegen::{BreakpointInfo, BreakpointMap}; use crate::state::x64::{build_instance_image, read_stack, X64Register, GPR, XMM}; -use crate::state::CodeVersion; +use crate::state::{CodeVersion, ExecutionStateImage}; use crate::vm; use libc::{mmap, mprotect, siginfo_t, MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE}; use nix::sys::signal::{ @@ -344,17 +344,9 @@ extern "C" fn signal_trap_handler( } let ctx: &mut vm::Ctx = &mut **CURRENT_CTX.with(|x| x.get()); - let rsp = fault.known_registers[X64Register::GPR(GPR::RSP).to_index().0].unwrap(); - - let es_image = CURRENT_CODE_VERSIONS.with(|versions| { - let versions = versions.borrow(); - read_stack( - || versions.iter(), - rsp as usize as *const u64, - fault.known_registers, - Some(fault.ip.get() as u64), - ) - }); + let es_image = fault + .read_stack(None) + .expect("fault.read_stack() failed. Broken invariants?"); if is_suspend_signal { let image = build_instance_image(ctx, es_image); @@ -431,6 +423,26 @@ pub struct FaultInfo { pub known_registers: [Option; 24], } +impl FaultInfo { + pub unsafe fn read_stack(&self, max_depth: Option) -> Option { + let rsp = match self.known_registers[X64Register::GPR(GPR::RSP).to_index().0] { + Some(x) => x, + None => return None, + }; + + Some(CURRENT_CODE_VERSIONS.with(|versions| { + let versions = versions.borrow(); + read_stack( + || versions.iter(), + rsp as usize as *const u64, + self.known_registers, + Some(self.ip.get() as u64), + max_depth, + ) + })) + } +} + #[cfg(all(target_os = "linux", target_arch = "aarch64"))] pub unsafe fn get_fault_info(siginfo: *const c_void, ucontext: *mut c_void) -> FaultInfo { #[allow(dead_code)] diff --git a/lib/runtime-core/src/state.rs b/lib/runtime-core/src/state.rs index e31e55bb4..4a1bf5d0a 100644 --- a/lib/runtime-core/src/state.rs +++ b/lib/runtime-core/src/state.rs @@ -875,12 +875,19 @@ pub mod x64 { mut stack: *const u64, initially_known_registers: [Option; 24], mut initial_address: Option, + max_depth: Option, ) -> ExecutionStateImage { let mut known_registers: [Option; 24] = initially_known_registers; let mut results: Vec = vec![]; let mut was_baseline = true; - for _ in 0.. { + for depth in 0.. { + if let Some(max_depth) = max_depth { + if depth >= max_depth { + return ExecutionStateImage { frames: results }; + } + } + let ret_addr = initial_address.take().unwrap_or_else(|| { let x = *stack; stack = stack.offset(1); @@ -891,7 +898,7 @@ pub mod x64 { let mut is_baseline: Option = None; for version in versions() { - println!("Lookup IP: {:x}", ret_addr); + //println!("Lookup IP: {:x}", ret_addr); match version .msm .lookup_call_ip(ret_addr as usize, version.base) @@ -1079,7 +1086,7 @@ pub mod x64 { stack: wasm_stack, locals: wasm_locals, }; - println!("WFS = {:?}", wfs); + //println!("WFS = {:?}", wfs); results.push(wfs); }