Wgpu-rs: Segfault from traingle example if I add a dependency (rusty_v8)

Created on 10 Sep 2020  路  5Comments  路  Source: gfx-rs/wgpu-rs

Hi,

I'm getting a segfault from the triangle example when I try to add v8 to it. Steps:

  1. I copied the 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.

The line that actually crashes is this: https://github.com/KhronosGroup/SPIRV-Cross/blob/master/spirv_cross_parsed_ir.cpp#L156 with the error EXC_BAD_ACCESS. It looks like name is just an empty string in the debugger.

It's really strange to me that all I have to do is add the "use" to get the segfault. Maybe it's got something to do with include_spirv and how that gets packaged and v8 alters that? Anyway I was hoping someone here had seen something similar or knew what this might be about.

rustc 1.46.0. OSX 10.13.6.

Also posted about this here: https://github.com/denoland/rusty_v8/issues/465

help wanted question

Most helpful comment

It looks like the problem is related to different libc++ implementations being used in rusty_v8 and spirv_cross.

rusty_v8 includes a static library that's pre-built (librusty_v8.a) with a particular custom libc++, but spirv_cross uses whatever is available on the system when it's being built. Because the different libc++ implementations aren't necessarily binary compatible, values end up being assigned wrong fields (e.g. c from above is assigned to the string's internal __size_ when rusty_v8 is loaded).

For example, we can see that librusty_v8.a includes string.o (otool -L librusty_v8.a | grep string.o). We can extract string.o with ar x librusty_v8.a. Now if we look at the contents with objdump -t string.o | c++filt, we can see symbols related to a string implementation and GCC (https://gist.github.com/grovesNL/dda60c1281b5c74d49eb419547df58a8). But ideally this wouldn't contain parts of libc++, instead we'd like to use whatever libc++ is available on the system whatever is installed on the user's machine (Clang in my case, to match spirv_cross).

I also just came across this rusty_v8 issue which mentions that it might be possible to use the system's libc++ by passing use_custom_libcxx=false in the GN configuration in rusty_v8.

All 5 comments

I can reproduce this but it's not clear what's happening here yet.

The string in that stack frame is supposed to be main. Before we add rusty_v8, we do see main there. After we add rusty_v8 though, we see the string is somehow offset by one to become ain with \x04 at the end:

image

@grovesNL Where is this string coming from exactly? Is it packaged into the executable or read at runtime?

main is the name of the entry point in the SPIR-V file. The SPIR-V file is included into the executable (with include_bytes through include_spirv) but still needs to be parsed at runtime.

I'll take a closer look soon and try to track down what's happening here. Everything on the Rust side seems to be fine, so maybe something about the C++ parts of spirv_cross and rusty_v8 not playing nicely somehow. While I was stepping through the C++ function extract_string, I noticed some unexpected behavior in extract_string when rusty_v8 is loaded. It seems like the first character to be appended to ret (during ret += c;) is not actually appended somehow, and in turn causes everything to be offset by one position in the string.

It looks like the problem is related to different libc++ implementations being used in rusty_v8 and spirv_cross.

rusty_v8 includes a static library that's pre-built (librusty_v8.a) with a particular custom libc++, but spirv_cross uses whatever is available on the system when it's being built. Because the different libc++ implementations aren't necessarily binary compatible, values end up being assigned wrong fields (e.g. c from above is assigned to the string's internal __size_ when rusty_v8 is loaded).

For example, we can see that librusty_v8.a includes string.o (otool -L librusty_v8.a | grep string.o). We can extract string.o with ar x librusty_v8.a. Now if we look at the contents with objdump -t string.o | c++filt, we can see symbols related to a string implementation and GCC (https://gist.github.com/grovesNL/dda60c1281b5c74d49eb419547df58a8). But ideally this wouldn't contain parts of libc++, instead we'd like to use whatever libc++ is available on the system whatever is installed on the user's machine (Clang in my case, to match spirv_cross).

I also just came across this rusty_v8 issue which mentions that it might be possible to use the system's libc++ by passing use_custom_libcxx=false in the GN configuration in rusty_v8.

@grovesNL Thanks! That does seem to be the likely culprit. I'll close this issue and pursue on the rusty_v8 side

Was this page helpful?
0 / 5 - 0 ratings

Related issues

donpdonp picture donpdonp  路  3Comments

bvssvni picture bvssvni  路  5Comments

chinedufn picture chinedufn  路  3Comments

sagacity picture sagacity  路  3Comments

imjasonmiller picture imjasonmiller  路  3Comments