Comments (7)
Yeah. The TrapSink
interface allows for the creation of a map from PC addresses to wasm trap ID and bytecode offset, but it does require that signals be caught and have access to the saved state. SpiderMonkey does this, on all its supported platforms, so it is doable.
So we have a few options here. One is to start building up a signal handling library and handling the signals. I imagine we'd start by just exiting the process cleanly, which shouldn't be too complex. We could then incrementally work on printing out the trap code and/or bytecode offset, or further, unwinding the stack and allowing the embedder to recover, which are doable, but more work.
Another would be to add a feature to cranelift for calling a designated callback when a trap would otherwise occur. This would make the generated code bigger, and preclude the heap guard optimizations and require explicit bounds checks on all heap accesses, but it would make it easier to embed wasmtime in environments where signals aren't available.
from wasmtime.
Hm, correct me if my thinking is too naive, but is it that difficult to start with signals with unwinding right away?
I thought that it is as simple as:
- before jumping to the generated code in
execute
callsetjmp
- set the signal handler for SIGILL (for
ud2
), SIGBUS and SIGSEGV - in the handler check if the signal comes from the generated code, translate signal info to trapcode and fetch location etc. Save that info somewhere, possibly fetch somehow
vmctx
or store it thru thethread_local
(if that's signal safe enough ¯_(ツ)_/¯) longjmp
back toexecute
. Return trap info asErr
would that work or am I missing something?
from wasmtime.
Interesting idea. I don't know how reliable longjmp from signal handlers is on various platforms these days. I believe does work on at least some though, so I wouldn't be opposed to having that as an option.
If we ever allow wasm to call into arbitrary native code and vice versa, we'd probably want to do a new setjmp each time we call back into the wasm code, so that we don't unwind through native Rust code with setjmp, but that's doable.
In the future, another option would be to do an unwind. Cranelift doesn't yet support .eh_frame
or other metadata needed by native unwinders, but if we added that, then we could do a plain unwind all the way through both wasm and native code at once.
from wasmtime.
I don't know how reliable longjmp from signal handlers is on various platforms these days. I believe does work on at least some though, so I wouldn't be opposed to having that as an option.
Ha! Just implemented (or rather hacked :) ) setting a signal handler for SIGILL
and catching unreachable
/ud2
on a macOS machine and it works! I think, there is a good chance that it will work on Linux as well. Theoretically I can also test on Windows machine.
Regarding the second option: is it actually safe? For example, what if that native code wasn't compiled with unwind metadata?
from wasmtime.
Fun!
For unwinding, yeah, that may require all native code to be unwindable. On x86-64 System-V ABIs, LLVM and GCC both emit .eh_frame sections for all code, including C code. Other unwinders also have the ability to at least follow frame pointers. Ultimately we'd have to check each platform to see what's supported, but it'd be an option, and it's one we might need to explore eventually anyway when wasm gets support for EH.
from wasmtime.
I've verified that my code runs correctly on the linux machine!
However, I've ran into a problem: it's unclear how to read and write data from the signal handler. We need to read data for longjmp
use and we need to write data to pass illegal instruction address or faulting address back to execute
to translate this data to useful form.
It turned out that thread_local
is actually not safe enough (rust-lang/rust#43146), and we can't use global variables for that since it's not thread-safe.
Also, it is not clear to me how to get vmctx
without resorting to black magic.
How does SpiderMonkey solve this issue?
from wasmtime.
The short answer is that SpiderMonkey doesn't use Rust's std::thread_local
to do this.
I don't know of a way to do this in safe Rust. With unsafe code, we could have a global (not thread-local) variable hold a raw vmctx pointer. It can be statically initialized to null, and assigned the vmctx value before we call into any JIT code. Then, the signal handler can read it, and if it's null, it means we're not in JIT code. If it's non-null, then it points to a data structure where we can keep the known ranges of JIT code and use them to determine if that's where the fault happened.
And we can have variations on that if we want to support multiple wasmtime instances in the same process.
from wasmtime.
Related Issues (20)
- Fail to create link file with AT_SYMLINK_FOLLOW parameter. HOT 1
- wasmtime main.wasm ,then encounter an error: `gojs::runtime.scheduleTimeoutEvent` has not been defined HOT 1
- Feedback on some changes between wasmtime 17 and 21 HOT 1
- `wasmtime serve` can't run components requiring >10MB of memory by default HOT 7
- riscv64: Panic using the Zicond extension
- Winch: Assertion failure with saturating conversion instructions HOT 2
- Cranelift: JIT assertion failure when using `ArgumentPurpose::StructArgument` on macOS (A64) HOT 4
- [Partially answered myself] [Question] Problems with leveraging `cargo component` and `wasmtime-wasi` to run a "plugin" on the host HOT 3
- Is it possible to abort a component function call without fueling mechanism? HOT 1
- O_TRUNC setting.
- riscv64: Panic about worst_case_size for ReturnCall HOT 2
- What should the default behavior of `wasmtime serve` be with scheme/authority? HOT 13
- how can I access file system with k8s? HOT 2
- index out of bounds in crates/cranelift/src/debug/transform/attr.rs HOT 1
- feature pooling-allocator doesn't compile on its own HOT 2
- `#include <wasmtime/conf.h>` fails since `conf.h` is not generated HOT 10
- `wasi-common`: Does `sync` crate feature really rely on `wasmtime` dependency?
- Cranelift: jit: "region" "2.2.0" dependency doesn't compile on OpenBSD 7.5 HOT 2
- libunwind warning when compiling a wasmtime project against musl HOT 8
- Unable to link a binary with wasmtime and musl HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from wasmtime.