Allow accessing execution state in middleware breakpoint handlers.

This commit is contained in:
losfair 2019-10-13 20:51:39 +08:00
parent 128b006bf7
commit b0b0983eb8
3 changed files with 36 additions and 16 deletions

View File

@ -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<FCG: FunctionCodeGenerator<E>, RM: RunnableModule, E: Debug> {

View File

@ -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<u64>; 24],
}
impl FaultInfo {
pub unsafe fn read_stack(&self, max_depth: Option<usize>) -> Option<ExecutionStateImage> {
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)]

View File

@ -875,12 +875,19 @@ pub mod x64 {
mut stack: *const u64,
initially_known_registers: [Option<u64>; 24],
mut initial_address: Option<u64>,
max_depth: Option<usize>,
) -> ExecutionStateImage {
let mut known_registers: [Option<u64>; 24] = initially_known_registers;
let mut results: Vec<WasmFunctionStateDump> = 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<bool> = 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);
}