-
Notifications
You must be signed in to change notification settings - Fork 951
fix(wasip2): fix environment initialization in reactors #4482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Using `init()` to initialize stdio or environment is prone to race conditions for reactor-style components, e.g. `wasi:http/incoming-handler` interface implementations due to the fact that `init()` is normally used to "register" the export implementation In result, using e.g. `fmt.Println` may cause a runtime panic as follows: ``` ERROR wasmtime_cli::commands::serve: [125] :: Error { context: "error while executing at wasm backtrace:\n 0: 0x548e9 - wit-component:shim!indirect-wasi:io/[email protected][method]output-stream.blocking-write-and-flush\n 1: 0x4d56 - main!(internal/wasi/io/v0.2.0/streams.OutputStream).BlockingWriteAndFlush\n 2: 0x99f0 - main!syscall.writeStream\n 3: 0x96a0 - main!write\n 4: 0x4623 - main!(os.unixFileHandle).Write\n 5: 0x3cf5 - main!wasi:http/[email protected]#handle\nnote: using the `WASMTIME_BACKTRACE_DETAILS=1` environment variable may show more debugging information", source: "unknown handle index 0", } error: hyper::Error(User(Service), guest never invoked `response-outparam::set` method: error while executing at wasm backtrace: 0: 0x548e9 - wit-component:shim!indirect-wasi:io/[email protected][method]output-stream.blocking-write-and-flush 1: 0x4d56 - main!(internal/wasi/io/v0.2.0/streams.OutputStream).BlockingWriteAndFlush 2: 0x99f0 - main!syscall.writeStream 3: 0x96a0 - main!write 4: 0x4623 - main!(os.unixFileHandle).Write 5: 0x3cf5 - main!wasi:http/[email protected]#handle note: using the `WASMTIME_BACKTRACE_DETAILS=1` environment variable may show more debugging information Caused by: unknown handle index 0) ``` using `sync.OnceValue` to lazily initialize the environment instead of `init()` ensures correctness and should improve cold start times as a nice side effect (especially for applications not utilizing this functionality) Signed-off-by: Roman Volosatovs <[email protected]>
Signed-off-by: Roman Volosatovs <[email protected]>
Not exactly sure why, but looks like 1d20c31 is required to make the tests pass 🤔 |
I don't really understand the problem yet, because race conditions aren't really a thing in
Can you explain what's going on here? |
There are no dependencies here except for standard library and generated bindings using https://github.com/bytecodealliance/wasm-tools-go Writing to stdio in By some reason the initializers for stdio do not run before stdio is used. This PR is a quickfix, which fixes that. I will investigate the |
bytecodealliance/wasmtime#7592 Seems relevant |
If I'd like to understand what's going on here before merging, to make sure we're fixing the right bug. You can maybe try putting a |
This PR is meant to address the immediate symptoms of what appears to be a bigger problem indeed. I can try calling a function from So unless variable assignments in |
They are. Many variables are already initialized by a compiler pass as an optimization. Which variables are initialized like this is unspecified, but simple assignments like this one are typically done at compile time. A function like |
I tried calling |
(sharing experience, not sure how much it helps) This can be replicated in a regular wasip2 component. Combinations:
yields
looks like symbols & pointers work fine, but things that require |
Ok, clearly the bug here is that package initializers are not being run. I don't know what the exact problem is, but the proposed fix here doesn't fix the root cause (it only hides some symptoms of the bug). Closing, since this is the wrong way to fix this bug. I am pretty sure you should adjust your wasm VM to call |
Using
init()
to initialize stdio or environment is prone to race conditions for reactor-style components, e.g.wasi:http/incoming-handler
interface implementations due to the fact thatinit()
is normally used to "register" the export implementationIn result, using e.g.
fmt.Println
may cause a runtime panic as follows:usingI had to preserve the "eager" initialization approach insync.OnceValue
to lazily initialize the environment instead ofinit()
ensures correctness and should improve cold start times as a nice side effect (especially for applications not utilizing this functionality)init()
, to allow tests to pass but not exactly sure whyThis issue can be reproduced using a
wasi:http/incoming-handler
implementation run in wasmtime 24For example, I used https://github.com/Mossaka/hello-wasi-http-tinygo, to which I've added a
fmt.Println
line at the top