Skip to content
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

Environment variables don't work if main isn't used #180

Closed
alexcrichton opened this issue Mar 4, 2020 · 1 comment · Fixed by #184
Closed

Environment variables don't work if main isn't used #180

alexcrichton opened this issue Mar 4, 2020 · 1 comment · Fixed by #184

Comments

@alexcrichton
Copy link
Collaborator

We discovered an issue in the Rust wasm32-wasi target today where a wasm binary uses std::env but doesn't end up importing the requisite wasi items to actually get env vars working.

The broken example looks like this:

#[no_mangle]
pub extern fn foo() {
    println!("{:?}", std::env::var("FOO"));
}

And when compiled:

$ rustc +nightly foo.rs --target wasm32-wasi -O --crate-type cdylib
$ wasm2wat foo.wasm | grep import
  (import "wasi_snapshot_preview1" "fd_write" (func $_ZN4wasi13lib_generated22wasi_snapshot_preview18fd_write17h8cb541fbb70a6a5bE (type 7)))

This is showing that environ_get isn't imported at all!

When compiled as a binary though it does indeed work:

fn main() {
    println!("{:?}", std::env::var("FOO"));
}
$ rustc +nightly foo.rs --target wasm32-wasi -O
$ wasm2wat foo.wasm | grep import
  (import "wasi_snapshot_preview1" "proc_exit" (func $__wasi_proc_exit (type 1)))
  (import "wasi_snapshot_preview1" "fd_write" (func $_ZN4wasi13lib_generated22wasi_snapshot_preview18fd_write17h8cb541fbb70a6a5bE (type 9)))
  (import "wasi_snapshot_preview1" "fd_prestat_get" (func $__wasi_fd_prestat_get (type 3)))
  (import "wasi_snapshot_preview1" "fd_prestat_dir_name" (func $__wasi_fd_prestat_dir_name (type 8)))
  (import "wasi_snapshot_preview1" "environ_sizes_get" (func $__wasi_environ_sizes_get (type 3)))
  (import "wasi_snapshot_preview1" "environ_get" (func $__wasi_environ_get (type 3)))

I'm told that @sunfishcode is working on a fix!

@syrusakbary
Copy link

Not sure if this is related:
#181

I encountered in programs with main

sunfishcode added a commit that referenced this issue Mar 10, 2020
This is the first in a series of PRs to make it easier to use WASI libc
in Wasm modules that don't have a `main` function. By initializing the
environment on demand, we avoid depending on having `__wasm_call_ctors`
run.

This uses weak symbols strategically to ensure that if `environ` is
used, it is initialized eagerly, but if only `getenv` and friends
are used, the environment is initialized lazily.

Eventually, I expect we'll have a convention for wasm modules without
main functions which will allow the `__wasm_call_ctors` function to be
called automatically, but this helps in simple cases for now.

Fixes #180.
sunfishcode added a commit that referenced this issue Mar 19, 2020
* Lazy-initialize the environment variables.

This is the first in a series of PRs to make it easier to use WASI libc
in Wasm modules that don't have a `main` function. By initializing the
environment on demand, we avoid depending on having `__wasm_call_ctors`
run.

This uses weak symbols strategically to ensure that if `environ` is
used, it is initialized eagerly, but if only `getenv` and friends
are used, the environment is initialized lazily.

Eventually, I expect we'll have a convention for wasm modules without
main functions which will allow the `__wasm_call_ctors` function to be
called automatically, but this helps in simple cases for now.

Fixes #180.

* Add comments explaining the libc-environ-compat.h header usage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants