rusty_v8 icon indicating copy to clipboard operation
rusty_v8 copied to clipboard

Segfaults if "use rusty_v8;" in wgpu application (OSX)

Open FredrikNoren opened this issue 5 years ago • 14 comments

Hi!

I'm getting a segfault when I'm trying to use this with wgpu. Steps:

  1. I copied their hello-triangle example. Works fine.
  2. I added rusty_v8 to my Cargo.toml. Things still work.
  3. Then I added use rusty_v8; to the top of my main.rs. It now crashes with a segfault 11. (I'm not even calling anything in v8 at this point, just the use). The call that segfaults is device.create_render_pipeline.

rustc 1.46.0. OSX 10.13.6.

Any ideas what might be going on? Or suggestions for how to debug it?

Edit: worth noting; if I add the example from the rusty_v8 to the top of my main func that runs fine, but it all segfaults like above anyway

FredrikNoren avatar Sep 09 '20 22:09 FredrikNoren

Probably a dupe of #147.

piscisaureus avatar Sep 11 '20 15:09 piscisaureus

@piscisaureus Looks like it yeah. I just tried to create a build with use_custom_libcxx=false but I'm getting: linking with cc failed: exit code: 1 on OSX. Any suggestion for how to fix that? This is the build output: https://github.com/FredrikNoren/rusty_v8/runs/1105589769?check_suite_focus=true

My steps:

  1. Forked this repo
  2. Added use_custom_libcxx=false: https://github.com/FredrikNoren/rusty_v8/commit/8d39830e55b77169e0b2ba1844ea5cfa6389c268

FredrikNoren avatar Sep 12 '20 13:09 FredrikNoren

@FredrikNoren You're already setting V8_FROM_SOURCE in the environment, right? If so, that's good.

It's invoking cc to link everything together but you probably want to use c++ instead.

bnoordhuis avatar Sep 12 '20 13:09 bnoordhuis

@bnoordhuis Yeah V8_FROM_SOURCE was already set in the github workflow when I forked this repo. Is there a way to force it to use the c++ linker?

It seems like the default config builds fine: https://github.com/FredrikNoren/rusty_v8/runs/1105821770?check_suite_focus=true (i.e. that is just plain forking this repo and hitting build)

I tried the configuration suggested in this SO post; GN_ARGS: is_clang=true use_custom_libcxx_for_host=false use_custom_libcxx=false libcxx_abi_unstable=false, but that also failed (same error from what I can tell): https://github.com/FredrikNoren/rusty_v8/runs/1105874562?check_suite_focus=true

FredrikNoren avatar Sep 12 '20 14:09 FredrikNoren

Ok I got it to build (on OSX and Win at least) with use_custom_libcxx=false use_custom_libcxx_for_host=true: https://github.com/FredrikNoren/rusty_v8/runs/1106865968?check_suite_focus=true

Then I used RUSTY_V8_MIRROR="https://github.com/FredrikNoren/rusty_v8/releases/download" cargo build. But I'm still getting the same segfault.

I tried running the nm command suggested in the other issue but I'm not sure what to look for here;

nm -demangle target/debug/testy | grep libc
00000001007d3ea0 t std::__1::__libcpp_refstring::__uses_refcount() const
00000001007e02f0 t std::__1::__libcpp_refstring::c_str() const
000000010079ce70 t std::__1::__libcpp_debug_info::what() const
00000001007c6470 t int std::__1::(anonymous namespace)::__libcpp_atomic_add<int, int>(int*, int, int)
00000001007e0610 t int std::__1::(anonymous namespace)::__libcpp_atomic_add<int, int>(int*, int, int)
00000001007db8f0 t unsigned long std::__1::(anonymous namespace)::__libcpp_atomic_add<unsigned long, unsigned long>(unsigned long*, unsigned long, int)
00000001007dbcf0 t void (*std::__1::(anonymous namespace)::__libcpp_atomic_load<void (*)()>(void (* const*)(), int))()
00000001007d3960 t void std::__1::(anonymous namespace)::__libcpp_atomic_store<unsigned long volatile, unsigned long>(unsigned long volatile*, unsigned long, int)
00000001007d3930 t void std::__1::(anonymous namespace)::__libcpp_relaxed_store<unsigned long volatile, unsigned long>(unsigned long volatile*, unsigned long)
00000001007bb920 t std::__1::enable_if<(__is_forward_iterator<char*>::value) && (__libcpp_string_gets_noexcept_iterator<char*>::value), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>::type std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append<char*>(char*, char*)
0000000100668ad0 T std::__1::enable_if<(__is_forward_iterator<char const*>::value) && (__libcpp_string_gets_noexcept_iterator<char const*>::value), std::__1::__wrap_iter<char*> >::type std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::insert<char const*>(std::__1::__wrap_iter<char const*>, char const*, char const*)
00000001006678e0 T std::__1::enable_if<(__is_forward_iterator<char*>::value) && (__libcpp_string_gets_noexcept_iterator<char*>::value), std::__1::__wrap_iter<char*> >::type std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::insert<char*>(std::__1::__wrap_iter<char const*>, char*, char*)
00000001007be4f0 t std::__1::enable_if<(__is_forward_iterator<wchar_t*>::value) && (__libcpp_string_gets_noexcept_iterator<wchar_t*>::value), std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&>::type std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >::append<wchar_t*>(wchar_t*, wchar_t*)
00000001007dbc10 t std::__1::__libcpp_tls_get(unsigned long)
00000001007dbb70 t std::__1::__libcpp_tls_set(unsigned long, void*)
000000010079af60 t std::__1::__libcpp_allocate(unsigned long, unsigned long)
00000001007d3be0 t std::__1::__libcpp_refstring::__libcpp_refstring(char const*)
00000001007d3da0 t std::__1::__libcpp_refstring::__libcpp_refstring(char const*)
00000001007e0250 t std::__1::__libcpp_refstring::~__libcpp_refstring()
00000001007e0530 t std::__1::__libcpp_refstring::~__libcpp_refstring()
000000010079a630 t std::__1::__libcpp_deallocate(void*, unsigned long, unsigned long)
00000001007d5700 t std::__1::__libcpp_debug_info::__libcpp_debug_info(char const*, int, char const*, char const*)
00000001007d9250 t std::__1::__libcpp_debug_info::__libcpp_debug_info(char const*, int, char const*, char const*)
00000001007de4d0 t std::__1::__libcpp_mutex_lock(_opaque_pthread_mutex_t*)
00000001007dbc30 t std::__1::__libcpp_tls_create(unsigned long*, void (*)(void*))
00000001007cf510 t unsigned long std::__1::__libcpp_acquire_load<unsigned long>(unsigned long const*)
00000001007e0890 t std::__1::__libcpp_condvar_wait(_opaque_pthread_cond_t*, _opaque_pthread_mutex_t*)
00000001007dbba0 t std::__1::__libcpp_execute_once(_opaque_pthread_once_t*, void (*)())
00000001007de540 t std::__1::__libcpp_mutex_unlock(_opaque_pthread_mutex_t*)
00000001013bf0e8 d std::__1::__libcpp_debug_function
00000001007cca90 t std::__1::__libcpp_numeric_limits<char, true>::max()
00000001007ccab0 t std::__1::__libcpp_numeric_limits<unsigned int, true>::max()
000000010079aea0 t std::__1::__libcpp_numeric_limits<long, true>::max()
00000001007d0560 t std::__1::__libcpp_numeric_limits<long, true>::min()
00000001007d0cb0 t std::__1::__libcpp_numeric_limits<unsigned long, true>::max()
00000001007d0900 t std::__1::__libcpp_numeric_limits<unsigned short, true>::max()
00000001007ccaa0 t std::__1::__libcpp_numeric_limits<wchar_t, true>::max()
00000001007d0720 t std::__1::__libcpp_numeric_limits<long long, true>::max()
00000001007d0710 t std::__1::__libcpp_numeric_limits<long long, true>::min()
00000001007d0ea0 t std::__1::__libcpp_numeric_limits<unsigned long long, true>::max()
00000001007e09d0 t std::__1::__libcpp_condvar_broadcast(_opaque_pthread_cond_t*)
000000010079d150 t std::__1::__libcpp_abort_debug_function(std::__1::__libcpp_debug_info const&)
00000001007e0860 t std::__1::__libcpp_thread_get_current_id()
000000010079a5d0 t long std::__1::__libcpp_atomic_refcount_decrement<long>(long&)
000000010079a700 t long std::__1::__libcpp_atomic_refcount_increment<long>(long&)

FredrikNoren avatar Sep 13 '20 08:09 FredrikNoren

I believe use_custom_libcxx_for_host is intended for cross-compiling. If you set it for a native build, it's equivalent to setting use_custom_libcxx=true.

The stack trace suggests libc++ was built with debugging enabled (-D_LIBCPP_DEBUG=...) but that will fail miserably if not all parts of the program are built with the exact same setting.

Check the config("runtime_library") section in build/config/c++/BUILD.gn - there are more compile and link flags that can have an impact. In particular, if you're building with clang++ (likely, since you're on macOS), make sure is_clang=true.

bnoordhuis avatar Sep 13 '20 09:09 bnoordhuis

@bnoordhuis It looks like -nostdlib++ is always set in build/config/c++/BUILD.gn: https://github.com/denoland/chromium_build/blob/6298d5546af5135b25e29a601b8414d0a16ecafb/config/c%2B%2B/BUILD.gn#L114 . But I'm guessing that for this to work it needs to be added back in somehow? I'm completely new to gn; any idea how to do that?

FredrikNoren avatar Sep 13 '20 09:09 FredrikNoren

Ok finally figured it out; I just needed to add println!("cargo:rustc-link-lib=dylib=c++"); to build.rs. These are my changes to make it work on OSX: https://github.com/FredrikNoren/rusty_v8/commit/262de8b125c4417fe2e3e8fe5bcbdbd3a937fb76

Would you guys be open to hosting binaries that aren't bundled with libstdc++? Haven't used feature flags for libs but maybe they could be used to control which one is used?

FredrikNoren avatar Sep 13 '20 22:09 FredrikNoren

This appears to be a blocker for https://github.com/denoland/deno/pull/7977 Any solution that doesn't require patching rusty_v8?

kvark avatar Oct 16 '20 20:10 kvark

Ideally librusty_v8.a would only include object code for the functions defined in src/bindings.cc (or at least the other functions should be hidden / non-exported). However I have no clue how to achieve that.

@bnoordhuis Do you know?

piscisaureus avatar Oct 18 '20 22:10 piscisaureus

I do, but I don't think that's the fix. It's not librusty_v8.a that's too promiscuous, it's librusty_v8.rlib, it re-exports the .a:

$ nm -C target/debug/librusty_v8.rlib | perl -ne 'print if /^[0-9a-f]+ T std::__1/' | head -10
0000000000000030 T std::__1::__rs_default::__rs_default(std::__1::__rs_default const&)
0000000000000000 T std::__1::__rs_default::__rs_default()
0000000000000030 T std::__1::__rs_default::__rs_default(std::__1::__rs_default const&)
0000000000000000 T std::__1::__rs_default::__rs_default()
0000000000000050 T std::__1::__rs_default::~__rs_default()
0000000000000050 T std::__1::__rs_default::~__rs_default()
00000000000000a0 T std::__1::__rs_default::operator()()
0000000000000120 T std::__1::__rs_get()
0000000000000000 T std::__1::__itoa::__u32toa(unsigned int, char*)
00000000000000b0 T std::__1::__itoa::__u64toa(unsigned long, char*)

I can think of workarounds at the linker level but rustc farms out linking to the system linker and what I have in mind works with GNU ld but not Apple ld.

bnoordhuis avatar Oct 19 '20 09:10 bnoordhuis

What if you just depend on v8 in the way that doesn't bundle a custom libcxx, and instead links to the system one?

kvark avatar Oct 19 '20 13:10 kvark

Probably won't work on Windows and older Linux machines. V8 & Chromium are fairly aggressive in adopting new C++ stdlib features.

bnoordhuis avatar Oct 19 '20 14:10 bnoordhuis

Would you guys be open to hosting binaries

I second this! It would be nice to at least have a mirror repo with up to date binaries.

marcushultman avatar Oct 21 '20 06:10 marcushultman