rust-lang / rust-bindgen

Automatically generates Rust FFI bindings to C (and some C++) libraries.
https://rust-lang.github.io/rust-bindgen/
BSD 3-Clause "New" or "Revised" License
4.45k stars 694 forks source link

SIGSEV invalid memory reference on Alpine musl with libclang-static and g++ 11.2 #2333

Open EKTehtris opened 2 years ago

EKTehtris commented 2 years ago

When building bindgen with clang static and gcc 11.2, it will fail with sigsev invalid memory reference, this is a conflict with clang-sys likely and newer gcc.

Error

localhost:~/rust-bindgen/bindgen-tests# cargo test --no-default-features --features static
    Finished test [unoptimized + debuginfo] target(s) in 0.04s
     Running unittests src/lib.rs (/root/rust-bindgen/target/debug/deps/bindgen_tests-cd32cb65c4995606)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running tests/stylo_sanity.rs (/root/rust-bindgen/target/debug/deps/stylo_sanity-c6e7b74ea8f748c0)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running tests/tests.rs (/root/rust-bindgen/target/debug/deps/tests-d5d9d9844a18f3e3)
error: test failed, to rerun pass '--test tests'

Caused by:
  process didn't exit successfully: `/root/rust-bindgen/target/debug/deps/tests-d5d9d9844a18f3e3` (signal: 11, SIGSEGV: invalid memory reference)

What was run

git clone https://github.com/rust-lang/rust-bindgen
cd rust-bindgen/bindgen-tests
sed -i 's|bindgen = { path = "../bindgen" }|bindgen = { path = "../bindgen" ,default-features=false}|' Cargo.toml
cargo test --features static

Note : I had to remove the default-features because features are not exclusive in that setup so adding static will conflict with runtime

Setup

localhost:~# uname -a
Linux localhost 5.15.74-0-lts #1-Alpine SMP Sat, 15 Oct 2022 18:26:49 +0000 x86_64 Linux

localhost:~# c++ --version
c++ (Alpine 11.2.1_git20220219) 11.2.1 20220219
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

localhost # cc --version
cc (Alpine 11.2.1_git20220219) 11.2.1 20220219
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

localhost:~# clang --version
Alpine clang version 13.0.1
Target: x86_64-alpine-linux-musl
Thread model: posix
InstalledDir: /usr/bin

How to reproduce

Install alpine 3.16 64bits (you can also use docker: docker run -it --rm alpine:3.16 sh)

apk update
apk add clang-static llvm-dev zlib-dev libffi-dev ncurses-dev gcc g++ git rustup 
rustup-init -y
source $HOME/.cargo/env

Then follow the previous paragraph (What was run)

Other information

commit tested : 9c32b460481903d90c6ac5df277bfa853a0558d8

Tested back until ^0.50, confirmed still a bug and related to new g++

GDB

/rust-bindgen/bindgen-tests # apk add gdb
(1/1) Installing gdb (11.2-r0)
Executing busybox-1.35.0-r17.trigger
OK: 959 MiB in 64 packages
/rust-bindgen/bindgen-tests # gdb --args cargo test --features static
GNU gdb (GDB) 11.2
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-alpine-linux-musl".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from cargo...
(No debugging symbols found in cargo)
(gdb) run
Starting program: /root/.cargo/bin/cargo test --features static
warning: Error disabling address space randomization: Operation not permitted
process 1587 is executing new program: /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo
[New LWP 1591]
    Finished test [unoptimized + debuginfo] target(s) in 0.05s

Thread 2 "cargo" received signal SIGUSR1, User defined signal 1.
[Switching to LWP 1591]
0x00007f3fa03394a3 in ?? () from /lib/ld-musl-x86_64.so.1
(gdb) bt
#0  0x00007f3fa03394a3 in ?? () from /lib/ld-musl-x86_64.so.1
#1  0x00007f3fa03366fa in ?? () from /lib/ld-musl-x86_64.so.1
#2  0x00007f3f92195b74 in ?? ()
#3  0x0000000000000000 in ?? ()
(gdb) 
emilio commented 2 years ago

It seems cargo is what's crashing? That's not a very useful stack either, it'd be nice if there were debug symbols.

EKTehtris commented 2 years ago

It seems cargo is what's crashing? That's not a very useful stack either, it'd be nice if there were debug symbols.

I don't know why the symbols are not shipped for musl target, they should be as per https://github.com/rust-lang/rust/pull/90733

maribu commented 1 year ago

Could you re-try after doing

$ export RUSTFLAGS=-Ctarget-feature=-crt-static

?

EKTehtris commented 1 year ago

This does work but I would get lot of poisoned instance on my tests (even with -- --test-threads=1.

Could you re-try after doing

$ export RUSTFLAGS=-Ctarget-feature=-crt-static

?

maribu commented 1 year ago

My "solution" to this is to replace the symlink from rustc to /usr/bin/rustup-init with this:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    static char *rustc = "rustc";
    static char *fix_linking = "-Ctarget-feature=-crt-static";
    char **args = calloc(sizeof(char *), argc + 1);
    if (!args) {
        puts("calloc() failed");
        return EXIT_FAILURE;
    }

    args[0] = rustc;
    args[1] = fix_linking;

    int pos = 1;
    while (argv[pos] != NULL) {
        args[pos + 1] = argv[pos];
        pos++;
    }

    int retval = execv("/usr/bin/rustup-init", args);
    printf("execv() failed with: %d\n", retval);
    return EXIT_FAILURE;
}
Karrq commented 1 year ago

I have the same issue and the above RUSTFLAGS doesn't fix it for me. I tried installing bindgen-cli to see if that would work and it does, so now I'm confused.

I guess at worst I can invoke it instead of using the library directly...

EDIT: I now realized that when ran without actually analyzing headers, the application doesn't attempt to open the shared library, thus no error seem to occur, but once used to actually analyze headers the library fails to link dynamically