mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-25 02:12:13 +00:00
Debugging LLVM trap code WIP
This commit is contained in:
parent
89af5dc107
commit
2bbe3406cf
@ -49,9 +49,7 @@ typedef struct {
|
|||||||
visit_fde_t visit_fde;
|
visit_fde_t visit_fde;
|
||||||
} callbacks_t;
|
} callbacks_t;
|
||||||
|
|
||||||
typedef struct {
|
using runtime_error_t = void*;
|
||||||
size_t data;
|
|
||||||
} runtime_error_t;
|
|
||||||
|
|
||||||
enum WasmTrapType {
|
enum WasmTrapType {
|
||||||
Unreachable = 0,
|
Unreachable = 0,
|
||||||
@ -121,7 +119,7 @@ private:
|
|||||||
|
|
||||||
struct WasmErrorSink {
|
struct WasmErrorSink {
|
||||||
WasmTrapType *trap_out;
|
WasmTrapType *trap_out;
|
||||||
runtime_error_t *user_error;
|
runtime_error_t user_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WasmException : std::exception {
|
struct WasmException : std::exception {
|
||||||
@ -149,7 +147,9 @@ public:
|
|||||||
|
|
||||||
struct UserException : UncatchableException {
|
struct UserException : UncatchableException {
|
||||||
public:
|
public:
|
||||||
UserException(size_t data) : error_data({data}) {}
|
UserException(size_t data) {
|
||||||
|
error_data = reinterpret_cast<runtime_error_t>(data);
|
||||||
|
}
|
||||||
|
|
||||||
virtual std::string description() const noexcept override {
|
virtual std::string description() const noexcept override {
|
||||||
return "user exception";
|
return "user exception";
|
||||||
@ -159,7 +159,7 @@ public:
|
|||||||
runtime_error_t error_data;
|
runtime_error_t error_data;
|
||||||
|
|
||||||
virtual void write_error(WasmErrorSink &out) const noexcept override {
|
virtual void write_error(WasmErrorSink &out) const noexcept override {
|
||||||
*out.user_error = error_data;
|
out.user_error = error_data;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ result_t module_load(const uint8_t *mem_ptr, size_t mem_size,
|
|||||||
|
|
||||||
void module_delete(WasmModule *module) { delete module; }
|
void module_delete(WasmModule *module) { delete module; }
|
||||||
|
|
||||||
// Throw a pointer that's assumed to be `*mut RuntimeError` on the rust
|
// Throw a pointer that's assumed to be `*mut Option<RuntimeError>` on the rust
|
||||||
// side.
|
// side.
|
||||||
[[noreturn]] void throw_runtime_error(size_t data) {
|
[[noreturn]] void throw_runtime_error(size_t data) {
|
||||||
unsafe_unwind(new UserException(data));
|
unsafe_unwind(new UserException(data));
|
||||||
@ -288,7 +288,7 @@ void module_delete(WasmModule *module) { delete module; }
|
|||||||
|
|
||||||
bool cxx_invoke_trampoline(trampoline_t trampoline, void *ctx, void *func,
|
bool cxx_invoke_trampoline(trampoline_t trampoline, void *ctx, void *func,
|
||||||
void *params, void *results, WasmTrapType *trap_out,
|
void *params, void *results, WasmTrapType *trap_out,
|
||||||
runtime_error_t *user_error, void *invoke_env) noexcept {
|
runtime_error_t user_error, void *invoke_env) noexcept {
|
||||||
try {
|
try {
|
||||||
catch_unwind([trampoline, ctx, func, params, results]() {
|
catch_unwind([trampoline, ctx, func, params, results]() {
|
||||||
trampoline(ctx, func, params, results);
|
trampoline(ctx, func, params, results);
|
||||||
|
@ -52,8 +52,6 @@ extern "C" {
|
|||||||
fn throw_trap(ty: i32) -> !;
|
fn throw_trap(ty: i32) -> !;
|
||||||
fn throw_breakpoint(ty: i64) -> !;
|
fn throw_breakpoint(ty: i64) -> !;
|
||||||
|
|
||||||
/// This should be the same as spliting up the fat pointer into two arguments,
|
|
||||||
/// but this is cleaner, I think?
|
|
||||||
#[cfg_attr(nightly, unwind(allowed))]
|
#[cfg_attr(nightly, unwind(allowed))]
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
fn throw_runtime_error(data: *mut Option<RuntimeError>) -> !;
|
fn throw_runtime_error(data: *mut Option<RuntimeError>) -> !;
|
||||||
|
@ -944,8 +944,10 @@ pub unsafe extern "C" fn callback_trampoline(
|
|||||||
b: *mut Option<RuntimeError>,
|
b: *mut Option<RuntimeError>,
|
||||||
callback: *mut BreakpointHandler,
|
callback: *mut BreakpointHandler,
|
||||||
) {
|
) {
|
||||||
|
dbg!("In llvm's callback_trampoline");
|
||||||
let callback = Box::from_raw(callback);
|
let callback = Box::from_raw(callback);
|
||||||
let result: Result<(), RuntimeError> = callback(BreakpointInfo { fault: None });
|
let result: Result<(), RuntimeError> = callback(BreakpointInfo { fault: None });
|
||||||
|
dbg!(&*b);
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => *b = None,
|
Ok(()) => *b = None,
|
||||||
Err(e) => *b = Some(e),
|
Err(e) => *b = Some(e),
|
||||||
|
@ -296,7 +296,7 @@ impl std::fmt::Display for RuntimeError {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
// TODO: update invoke error formatting
|
// TODO: update invoke error formatting
|
||||||
RuntimeError::InvokeError(_) => write!(f, "Error when calling invoke"),
|
RuntimeError::InvokeError(ie) => write!(f, "Error when calling invoke: {:?}", ie),
|
||||||
RuntimeError::Metering(_) => write!(f, "unknown metering error type"),
|
RuntimeError::Metering(_) => write!(f, "unknown metering error type"),
|
||||||
RuntimeError::InstanceImage(_) => write!(
|
RuntimeError::InstanceImage(_) => write!(
|
||||||
f,
|
f,
|
||||||
|
@ -281,7 +281,7 @@ extern "C" fn signal_trap_handler(
|
|||||||
let mut should_unwind = false;
|
let mut should_unwind = false;
|
||||||
let mut unwind_result: Option<Box<RuntimeError>> = None;
|
let mut unwind_result: Option<Box<RuntimeError>> = None;
|
||||||
let get_unwind_result = |uw_result: Option<Box<RuntimeError>>| -> Box<RuntimeError> {
|
let get_unwind_result = |uw_result: Option<Box<RuntimeError>>| -> Box<RuntimeError> {
|
||||||
uw_result
|
dbg!(uw_result)
|
||||||
.unwrap_or_else(|| Box::new(RuntimeError::InvokeError(InvokeError::FailedWithNoError)))
|
.unwrap_or_else(|| Box::new(RuntimeError::InvokeError(InvokeError::FailedWithNoError)))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -602,9 +602,9 @@ pub(crate) fn call_func_with_index_inner(
|
|||||||
if success {
|
if success {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
let error: RuntimeError = error_out
|
let error: RuntimeError = dbg!(error_out)
|
||||||
.map(Into::into)
|
.map_or_else(|| RuntimeError::InvokeError(InvokeError::FailedWithNoError), Into::into);
|
||||||
.unwrap_or_else(|| RuntimeError::InvokeError(InvokeError::FailedWithNoError));
|
dbg!(&error);
|
||||||
Err(error.into())
|
Err(error.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -590,7 +590,7 @@ macro_rules! impl_traits {
|
|||||||
) {
|
) {
|
||||||
Ok(Rets::from_ret_array(rets))
|
Ok(Rets::from_ret_array(rets))
|
||||||
} else {
|
} else {
|
||||||
Err(error_out.map_or_else(|| RuntimeError::InvokeError(InvokeError::FailedWithNoError), Into::into))
|
Err(dbg!(error_out).map_or_else(|| RuntimeError::InvokeError(InvokeError::FailedWithNoError), Into::into))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user