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

Rust functions exported to C are dead code eliminated by emscripten despite being exported #66026

Closed
lopopolo opened this issue Nov 1, 2019 · 3 comments

Comments

@lopopolo
Copy link
Contributor

lopopolo commented Nov 1, 2019

$ rustc --version --verbose
rustc 1.40.0-nightly (c23a7aa77 2019-10-19)
binary: rustc
commit-hash: c23a7aa778b0dfeffbf83b099bdf971242c1e1ac
commit-date: 2019-10-19
host: x86_64-apple-darwin
release: 1.40.0-nightly
LLVM version: 9.0
$ emcc --version
emcc (Emscripten gcc/clang-like replacement) 1.39.1 (commit 1b1f08f356d3f10d91e50c09dda6d44372ca908c)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I am attempting to upgrade the toolchain of a Rust and C project to Rust nightly's support for the LLVM emscripten backend #63649.

The project has a crate that compiles a C static library. The C library depends on symbols that are exported from Rust code in the crate as no_mangle and pub unsafe extern "C".

The build preamble sets RUSTFLAGS to enable building Wasm with emcc and marks all of the Rust symbols as exported.

$ echo $RUSTFLAGS
-C link-arg=-s -C link-arg=WASM=1 -C link-arg=-s -C link-arg=ASSERTIONS=1 -C link-arg=-s -C link-arg=NO_EXIT_RUNTIME=1 -C link-arg=-s -C link-arg=ALLOW_MEMORY_GROWTH=1 -C link-arg=-s -C link-arg=TOTAL_MEMORY=67108864 -C link-arg=-s -C link-arg=TOTAL_STACK=33554432 -C link-arg=-s -C link-arg=ENVIRONMENT=web -C link-arg=-s -C link-arg=EXPORTED_FUNCTIONS=["_artichoke_value_to_ary","_artichoke_ary_new","_artichoke_ary_new_capa","_artichoke_ary_new_from_values","_artichoke_ary_splat","_artichoke_ary_clone","_artichoke_ary_ref","_artichoke_ary_pop","_artichoke_ary_shift","_artichoke_ary_unshift","_artichoke_ary_len","_artichoke_ary_concat","_artichoke_ary_push","_artichoke_ary_set","_artichoke_ary_check","_artichoke_gc_mark_ary","_artichoke_gc_mark_ary_size","_mrb_sys_value_is_nil","_mrb_sys_value_is_false","_mrb_sys_value_is_true","_mrb_sys_range_excl","_mrb_sys_obj_frozen","_mrb_sys_fixnum_to_cint","_mrb_sys_float_to_cdouble","_mrb_sys_cptr_ptr","_mrb_sys_basic_ptr","_mrb_sys_obj_ptr","_mrb_sys_proc_ptr","_mrb_sys_class_ptr","_mrb_sys_class_to_rclass","_mrb_sys_class_of_value","_mrb_sys_nil_value","_mrb_sys_false_value","_mrb_sys_true_value","_mrb_sys_fixnum_value","_mrb_sys_float_value","_mrb_sys_cptr_value","_mrb_sys_obj_value","_mrb_sys_class_value","_mrb_sys_module_value","_mrb_sys_data_value","_mrb_sys_proc_value","_mrb_sys_symbol_name","_mrb_sys_new_symbol","_mrb_sys_set_instance_tt","_mrb_sys_data_init","_mrb_sys_raise","_mrb_sys_raise_current_exception","_mrb_sys_value_debug_str","_mrb_sys_ary_len","_mrb_sys_gc_arena_save","_mrb_sys_gc_arena_restore","_mrb_sys_gc_disable","_mrb_sys_gc_enable","_mrb_sys_value_is_dead","_mrb_sys_gc_live_objects","_mrb_sys_safe_gc_mark","_main","_malloc","_artichoke_web_repl_init","_artichoke_string_new","_artichoke_string_free","_artichoke_string_getlen","_artichoke_string_getch","_artichoke_string_putch","_artichoke_eval"] -C link-arg=-s -C link-arg=EXTRA_EXPORTED_RUNTIME_METHODS=["ccall","cwrap"]

The C static library has a macro for injecting an extern like modifier. The build.rs defines this macro to be __attribute__((used)) to match the EMSCRIPTEN_KEEPALIVE macro.

This code compiles and links, but when the application attempts to call a Rust exported symbol from C, Chrome raises a runtime error saying the function is unreachable.

VM5097:10526 Uncaught RuntimeError: unreachable
    at unreachable:artichoke_ary_push (wasm-function[50]:0x58b7)
    at hash_vals_i (wasm-function[7079]:0x32fba8)
    at ht_foreach (wasm-function[7039]:0x32a4a0)
    at mrb_hash_values (wasm-function[7078]:0x32faa5)
    at dynCall_viii (wasm-function[11266]:0x48ac54)
    at Module.dynCall_viii (eval at module.exports (webpack:///../node_modules/script-loader/addScript.js?), <anonymous>:10366:40)
    at invoke_viii (eval at module.exports (webpack:///../node_modules/script-loader/addScript.js?), <anonymous>:10523:5)
    at mrb_vm_exec (wasm-function[6396]:0x29d490)
    at mrb_vm_run (wasm-function[6386]:0x25f3b4)
    at mrb_top_run (wasm-function[6412]:0x2a84bc)

This function is explicitly exported and linking succeeds.

I'm not sure what is going on here. Any ideas?

@lopopolo
Copy link
Contributor Author

lopopolo commented Nov 1, 2019

I wasn't sure if the correct home for this issue was here or emscripten. I'm hoping we can figure that out 😄

@jonas-schievink
Copy link
Contributor

Are you sure the unreachable means that the function is missing? It looks to me like it was called without problems, and then raised an exception with the text "unreachable". The artichoke_ary_push function is here:

https://github.com/artichoke/artichoke/blob/d8a2b74076ce81690934531aa53de1ba3894f7a0/artichoke-backend/src/extn/core/array/ffi.rs#L189

@lopopolo
Copy link
Contributor Author

Thanks for taking a look Jonas. There is some UB and segfaults going on in this bit of code. I’ve decided to abandon this investigation and instead will focus on removing my dependency on the mruby C code.

Closing.

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

No branches or pull requests

2 participants