Skip to content

Commit

Permalink
Refinement.
Browse files Browse the repository at this point in the history
  • Loading branch information
olonho committed Apr 2, 2021
1 parent bab3d18 commit a2cc2f0
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 20 deletions.
9 changes: 6 additions & 3 deletions runtime/near-vm-errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub enum FunctionCallError {
MethodResolveError(MethodResolveError),
/// A trap happened during execution of a binary
WasmTrap(WasmTrap),
WasmUnknownError,
WasmUnknownError(String),
HostError(HostError),
EvmError(EvmError),
/// Non-deterministic error.
Expand Down Expand Up @@ -65,6 +65,8 @@ pub enum WasmTrap {
StackOverflow,
/// Generic trap.
GenericTrap,
/// Indirect call to null.
IndirectCallToNull,
}

#[derive(
Expand Down Expand Up @@ -355,8 +357,8 @@ impl fmt::Display for FunctionCallError {
FunctionCallError::HostError(e) => e.fmt(f),
FunctionCallError::LinkError { msg } => write!(f, "{}", msg),
FunctionCallError::WasmTrap(trap) => write!(f, "WebAssembly trap: {}", trap),
FunctionCallError::WasmUnknownError => {
write!(f, "Unknown error during Wasm contract execution")
FunctionCallError::WasmUnknownError(msg) => {
write!(f, "Unknown error during Wasm contract execution: {}", msg)
}
FunctionCallError::EvmError(e) => write!(f, "EVM: {:?}", e),
FunctionCallError::Nondeterministic(msg) => {
Expand All @@ -381,6 +383,7 @@ impl fmt::Display for WasmTrap {
WasmTrap::MisalignedAtomicAccess => write!(f, "Misaligned atomic access trap."),
WasmTrap::GenericTrap => write!(f, "Generic trap."),
WasmTrap::StackOverflow => write!(f, "Stack overflow."),
WasmTrap::IndirectCallToNull => write!(f, "Indirect call to null."),
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions runtime/near-vm-runner/src/wasmer1_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl IntoVMError for wasmer::RuntimeError {
}
Some(TrapCode::OutOfBounds) => FunctionCallError::WasmTrap(WasmTrap::MemoryOutOfBounds),
Some(TrapCode::IndirectCallToNull) => {
FunctionCallError::WasmTrap(WasmTrap::IncorrectCallIndirectSignature)
FunctionCallError::WasmTrap(WasmTrap::IndirectCallToNull)
}
Some(TrapCode::BadSignature) => {
FunctionCallError::WasmTrap(WasmTrap::IncorrectCallIndirectSignature)
Expand All @@ -135,16 +135,16 @@ impl IntoVMError for wasmer::RuntimeError {
Some(TrapCode::UnreachableCodeReached) => {
FunctionCallError::WasmTrap(WasmTrap::Unreachable)
}
Some(TrapCode::Interrupt) => {
FunctionCallError::Nondeterministic("Wasmer interrupt".to_string())
}
Some(TrapCode::UnalignedAtomic) => {
FunctionCallError::WasmTrap(WasmTrap::MisalignedAtomicAccess)
}
Some(TrapCode::Interrupt) => {
FunctionCallError::Nondeterministic("Wasmer interrupt".to_string())
}
Some(TrapCode::VMOutOfMemory) => {
FunctionCallError::Nondeterministic("Wasmer out of memory".to_string())
}
None => FunctionCallError::Nondeterministic(error_msg),
None => panic!("Unknown error: {}", error_msg),
};
VMError::FunctionCallError(error)
}
Expand Down
15 changes: 8 additions & 7 deletions runtime/near-vm-runner/src/wasmer_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use near_primitives::runtime::fees::RuntimeFeesConfig;
use near_primitives::{
config::VMConfig, profile::ProfileData, types::CompiledContractCache, version::ProtocolVersion,
};
use near_vm_errors::FunctionCallError::WasmUnknownError;
use near_vm_errors::{CompilationError, FunctionCallError, MethodResolveError, VMError, WasmTrap};
use near_vm_logic::types::PromiseResult;
use near_vm_logic::{External, VMContext, VMLogic, VMLogicError, VMOutcome};
Expand Down Expand Up @@ -101,10 +100,9 @@ impl IntoVMError for wasmer_runtime::error::RuntimeError {
// invoke returns false and doesn't fill error info what Singlepass BE doesn't.
// Failed unwinder may happen in the case of deep recursion/stack overflow.
// Also can be thrown on unreachable instruction, which is quite unfortunate.
InvokeError::FailedWithNoError => {
println!("FailedWithNoError");
VMError::FunctionCallError(WasmUnknownError)
}
InvokeError::FailedWithNoError => VMError::FunctionCallError(
FunctionCallError::Nondeterministic("FailedWithNoError".to_string()),
),
// Indicates that a trap occurred that is not known to Wasmer.
// As of 0.17.0, thrown only from Cranelift BE.
InvokeError::UnknownTrap { address, signal } => {
Expand All @@ -115,12 +113,15 @@ impl IntoVMError for wasmer_runtime::error::RuntimeError {
);
}
// A trap that Wasmer knows about occurred.
// As of 0.17.1, can be thrown on C signals caught, for example OOM.
InvokeError::TrapCode { code, srcloc } => {
VMError::FunctionCallError(match *code as u32 {
0 /* Unreachable */ => FunctionCallError::WasmTrap(WasmTrap::Unreachable),
1 /* IncorrectCallIndirectSignature */ => FunctionCallError::WasmTrap(WasmTrap::IncorrectCallIndirectSignature),
2 /* MemoryOutOfBounds */ => FunctionCallError::WasmTrap(WasmTrap::MemoryOutOfBounds),
3 /* CallIndirectOOB */ => FunctionCallError::WasmTrap(WasmTrap::CallIndirectOOB),
4 /* IllegalArithmetic */ => FunctionCallError::WasmTrap(WasmTrap::IllegalArithmetic),
_ => FunctionCallError::Nondeterministic(format!("Wasmer trap {} at {}", code, srcloc)),
5 /* MisalignedAtomicAccess */ => FunctionCallError::WasmTrap(WasmTrap::MisalignedAtomicAccess),
_ => FunctionCallError::WasmUnknownError(format!("Wasmer trap {} at {}", code, srcloc)),
})
}
// A trap occurred that Wasmer knows about but it had a trap code that
Expand Down
28 changes: 24 additions & 4 deletions runtime/near-vm-runner/src/wasmtime_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,39 @@ pub mod wasmtime_runner {
}
} else {
match trap.trap_code() {
Some(TrapCode::UnreachableCodeReached) => {
VMError::FunctionCallError(FunctionCallError::WasmTrap(WasmTrap::Unreachable))
}
Some(TrapCode::StackOverflow) => {
VMError::FunctionCallError(FunctionCallError::WasmTrap(WasmTrap::StackOverflow))
}
Some(TrapCode::MemoryOutOfBounds) => VMError::FunctionCallError(
FunctionCallError::WasmTrap(WasmTrap::MemoryOutOfBounds),
),
Some(TrapCode::TableOutOfBounds) => VMError::FunctionCallError(
FunctionCallError::WasmTrap(WasmTrap::MemoryOutOfBounds),
),
Some(TrapCode::IndirectCallToNull) => VMError::FunctionCallError(
FunctionCallError::WasmTrap(WasmTrap::IndirectCallToNull),
),
Some(TrapCode::BadSignature) => VMError::FunctionCallError(
FunctionCallError::WasmTrap(WasmTrap::IncorrectCallIndirectSignature),
),
Some(TrapCode::IntegerOverflow) => VMError::FunctionCallError(
FunctionCallError::WasmTrap(WasmTrap::IllegalArithmetic),
),
Some(TrapCode::IntegerDivisionByZero) => VMError::FunctionCallError(
FunctionCallError::WasmTrap(WasmTrap::IllegalArithmetic),
),
Some(TrapCode::BadConversionToInteger) => VMError::FunctionCallError(
FunctionCallError::WasmTrap(WasmTrap::IllegalArithmetic),
),
Some(TrapCode::UnreachableCodeReached) => {
VMError::FunctionCallError(FunctionCallError::WasmTrap(WasmTrap::Unreachable))
}
Some(TrapCode::Interrupt) => VMError::FunctionCallError(
FunctionCallError::Nondeterministic("interrupt".to_string()),
),
_ => VMError::FunctionCallError(FunctionCallError::WasmUnknownError),
_ => VMError::FunctionCallError(FunctionCallError::WasmUnknownError(
"unknown trap".to_string(),
)),
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion runtime/runtime/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ pub(crate) fn action_function_call(
| FunctionCallError::LinkError { msg: _ }
| FunctionCallError::MethodResolveError(_)
| FunctionCallError::WasmTrap(_)
| FunctionCallError::WasmUnknownError
// TODO: shall we abort on unknown errors also?
| FunctionCallError::WasmUnknownError(_)
| FunctionCallError::HostError(_)
| FunctionCallError::EvmError(_) => {
result.result = Err(ActionErrorKind::FunctionCallError(err.to_string()).into());
Expand Down

0 comments on commit a2cc2f0

Please sign in to comment.