zonyitoo/context-rs

Failed to compile from i686 to x86_64.

Closed this issue · 28 comments

vi commented
   Compiling context v0.1.4
Build failed, waiting for other jobs to finish...
failed to run custom build command for `context v0.1.4`
Process didn't exit successfully: `/mnt/src/_/rust_mioco_test/target/debug/build/context-ca8e3979cf5f1cbc/build-script-build` (exit code: 101)
--- stdout
TARGET = Some("x86_64-unknown-linux-gnu")
OPT_LEVEL = Some("0")
PROFILE = Some("debug")
TARGET = Some("x86_64-unknown-linux-gnu")
debug=true opt-level=0
HOST = Some("i686-unknown-linux-gnu")
TARGET = Some("x86_64-unknown-linux-gnu")
TARGET = Some("x86_64-unknown-linux-gnu")
HOST = Some("i686-unknown-linux-gnu")
CC_x86_64-unknown-linux-gnu = None
CC_x86_64_unknown_linux_gnu = None
TARGET_CC = None
CC = None
HOST = Some("i686-unknown-linux-gnu")
TARGET = Some("x86_64-unknown-linux-gnu")
HOST = Some("i686-unknown-linux-gnu")
CFLAGS_x86_64-unknown-linux-gnu = None
CFLAGS_x86_64_unknown_linux_gnu = None
TARGET_CFLAGS = None
CFLAGS = None
running: "cc" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-m64" "-fPIC" "-o" "/mnt/src/_/rust_mioco_test/target/x86_64-unknown-linux-gnu/debug/build/context-ca8e3979cf5f1cbc/out/src/asm/i686/_context.o" "-c" "src/asm/i686/_context.S"
ExitStatus(ExitStatus(256))


command did not execute successfully, got: exit code: 1



--- stderr
src/asm/i686/_context.S: Assembler messages:
src/asm/i686/_context.S:41: Error: invalid instruction suffix for `pop'
src/asm/i686/_context.S:46: Error: invalid instruction suffix for `pop'
src/asm/i686/_context.S:61: Error: operand type mismatch for `push'
src/asm/i686/_context.S:85: Error: invalid instruction suffix for `pop'
src/asm/i686/_context.S:90: Error: invalid instruction suffix for `pop'
src/asm/i686/_context.S:117: Error: operand type mismatch for `push'
thread '<main>' panicked at 'explicit panic', /home/vi/.cargo/registry/src/github.com-48ad6e4054423464/gcc-0.3.21/src/lib.rs:772

Why does it try to compile something from i686 with -m64?

That's weird. In the library, I use the gcc crate to compile the library, so I didn't actually generate the -m64 option for you. See this line of code.

So the question becomes ... Why the gcc crate thinks you are in x86_64 mode?

vi commented

There should be -m64, but there should not be src/asm/i686, but src/asm/x86_64. Maybe host and target got confused somewhere?

Ah, you mean that you need to compile it as x86_64? You could do a simple test:

fn main() {
    let arch =
        if cfg!(target_arch = "x86_64") {
            "x86_64"
        } else if cfg!(target_arch = "x86") {
            "i686"
        } else if cfg!(target_arch = "arm") {
            "arm"
        } else if cfg!(target_arch = "mips") {
            "mips"
        } else if cfg!(target_arch = "mipsel") {
            "mipsel"
        } else {
            panic!("Unsupported architecture");
        };
    println!("Your arch is {}", arch);
}

It should print "i686" in your case, but you want it to be "x86_64". Maybe you have installed a i686 version of rustc?

vi commented
$ rustc tarch.rs 
$ ./tarch 
Your arch is i686
$ rustc tarch.rs  --target=x86_64-unknown-linux-gnu
$ ./tarch  
Your arch is x86_64

Actually was trying to build mioco, which uses context-rs as a dependency. Mioco's example just crashes on my i686 and I can't build it for x86_64 because of this.
Are all those problems because of everybody expects developer's host to be 64-bit nowadays?

Your crashes is on Debian x86? Ah ... Of course. I have noticed this for a long time, but I don't know why. I don't know why it crashes only on Debian x86. You could see the AppVeyor's build log, it can run well on Windows x86. And I don't have a x86 server, so this problem hangs for a long time.

This crate relies on Cargo's build script. So the problem becomes how to tell Cargo that you are using x86_64 instead of x86, because obviously, cargo build the build.rs with x86 rustc instead of x86_64, so it chooses the i686 version of asm codes.

vi commented

Yes. Also just simple ::std::thread::spawn crashes when build from Debian x86 to x86_64 (with approriate kernel), but it may be unrelated.

Shall I run some experiments on my Debian x86 to help with the issue?

You could just run cargo test and cargo test --release for this crate and see if it works perfectly on your x86 system. (It should produce SegmFault.) And because this crate is so simple, so the only reason is in the ASM code.

Also, you could run the examples in examples by cargo run --example [example_name] and cargo run --example [example_name] --release.

vi commented
v@l:17:22:48:~/src/git/context-rs$ cargo test
    Updating registry `https://github.com/rust-lang/crates.io-index`
   Compiling gcc v0.3.21
   Compiling winapi-build v0.1.1
   Compiling libc v0.2.5
   Compiling libc v0.1.12
/home/vi/.cargo/registry/src/github.com-48ad6e4054423464/libc-0.1.12/rust/src/liblibc/lib.rs:81:21: 81:39 warning: lint raw_pointer_derive has been removed: using derive with raw pointers is ok
/home/vi/.cargo/registry/src/github.com-48ad6e4054423464/libc-0.1.12/rust/src/liblibc/lib.rs:81 #![allow(bad_style, raw_pointer_derive)]
                                                                                                                    ^~~~~~~~~~~~~~~~~~
   Compiling winapi v0.2.5
   Compiling kernel32-sys v0.2.1
   Compiling log v0.3.5
   Compiling fs2 v0.2.2
   Compiling memmap v0.2.3
   Compiling context v0.2.0 (file:///mnt/src/git/context-rs)
     Running target/debug/context-d79e0580000076ee

running 4 tests
test stack::tests::stack_pool_caches_exact ... ok
test context::test::test_load_save_context ... ok
test stack::tests::stack_pool_caches ... ok
test context::test::test_swap_context ... ok

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests context

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

v@l:17:23:10:~/src/git/context-rs$ cargo test --release
   Compiling winapi-build v0.1.1
   Compiling libc v0.1.12
   Compiling gcc v0.3.21
   Compiling libc v0.2.5
/home/vi/.cargo/registry/src/github.com-48ad6e4054423464/libc-0.1.12/rust/src/liblibc/lib.rs:81:21: 81:39 warning: lint raw_pointer_derive has been removed: using derive with raw pointers is ok
/home/vi/.cargo/registry/src/github.com-48ad6e4054423464/libc-0.1.12/rust/src/liblibc/lib.rs:81 #![allow(bad_style, raw_pointer_derive)]
                                                                                                                    ^~~~~~~~~~~~~~~~~~
   Compiling winapi v0.2.5
   Compiling kernel32-sys v0.2.1
   Compiling log v0.3.5
   Compiling fs2 v0.2.2
   Compiling memmap v0.2.3
   Compiling context v0.2.0 (file:///mnt/src/git/context-rs)
     Running target/release/context-d79e0580000076ee

running 4 tests
test stack::tests::stack_pool_caches_exact ... ok
test context::test::test_swap_context ... ok
test stack::tests::stack_pool_caches ... ok
(It's hung with 100% of one CPU core)
^C
v@l:17:24:09:~/src/git/context-rs$ rustc --version
rustc 1.8.0-nightly (18b851bc5 2016-01-22)

Well, it should be the context::test:: test_load_save_context. Why this test spins forever? ... :/

How about the examples?

vi commented
v@l:17:56:18:~/src/git/context-rs$ rust-gdb -args target/release/context-d79e0580000076ee
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
Copyright (C) 2014 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 "i586-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://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 target/release/context-d79e0580000076ee...done.
(gdb) r
Starting program: /mnt/src/git/context-rs/target/release/context-d79e0580000076ee 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".

running 4 tests
[New Thread 0xf73ffb40 (LWP 24383)]
[New Thread 0xf6dffb40 (LWP 24385)]
[New Thread 0xf6fffb40 (LWP 24384)]
[New Thread 0xf63ffb40 (LWP 24386)]
[New Thread 0xf5dffb40 (LWP 24387)]
[New Thread 0xf57ffb40 (LWP 24390)]
[New Thread 0xf55ffb40 (LWP 24391)]
[Thread 0xf5dffb40 (LWP 24387) exited]
[Thread 0xf55ffb40 (LWP 24391) exited]
test context::test::test_swap_context ... ok
test stack::tests::stack_pool_caches ... ok
[Thread 0xf6fffb40 (LWP 24384) exited]
[New Thread 0xf55ffb40 (LWP 24392)]
[Thread 0xf63ffb40 (LWP 24386) exited]
[Thread 0xf55ffb40 (LWP 24392) exited]
test stack::tests::stack_pool_caches_exact ... ok
[Thread 0xf57ffb40 (LWP 24390) exited]
^C
Program received signal SIGINT, Interrupt.
pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/i386/i586/../i486/pthread_cond_wait.S:188
188 ../nptl/sysdeps/unix/sysv/linux/i386/i586/../i486/pthread_cond_wait.S: No such file or directory.
(gdb) bt
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/i386/i586/../i486/pthread_cond_wait.S:188
#1  0xf7eeb81c in __pthread_cond_wait (cond=0xf741d000, mutex=0xf741c000) at forward.c:149
#2  0x56599c75 in thread::park::h7ac806de49823538kCb ()
#3  0x565a3830 in sync::mpsc::blocking::WaitToken::wait::h344fb350e1a3dd4dw8m ()
#4  0x56574072 in sync::mpsc::Receiver$LT$T$GT$::recv::h9036032467095777498 ()
#5  0x565606c6 in run_tests_console::hf2e936fd72bc107b3Hb ()
#6  0x5655dbb0 in test_main::hf7c2799e538de465i2a ()
#7  0x56563c06 in test_main_static::hcc39db07781fc3a3x4a ()
#8  0x5655c916 in __test::main::h5b00c676c0758c07WJa ()
#9  0x565a81eb in sys_common::unwind::try::try_fn::h11685622327720074413 ()
#10 0x565a5535 in __rust_try ()
#11 0x565a7e78 in rt::lang_start::hbe954a33d7b1851dGwy ()
#12 0x5655c94e in main ()
(gdb) q
A debugging session is active.

    Inferior 1 [process 24379] will be killed.

Quit anyway? (y or n) y
vi commented

With RUST_TEST_THREADS=1 it hangs on the first test, context::test::test_load_save_context.

Well, it seems that the function never returns. Is there any different between Debian x86's call convention and the other x86 systems? Why not do try to run it in gdb with

r test_load_save_context

and run the program step by step.

Rust's testes launch randomly.

vi commented

In Debian, there may be some this additional flags for all C/C++ things: -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2. (note: this is not authoritative, I just copied that from random makefile).

The problem is the program is compiled by rustc, so the function call should meet Rust's own calling convention. I am going to install an ArchLinux x86 to test if it is work.

vi commented

What about the problem that this issue is about? cargo test --target=x86_64-unknown-linux-musl or cargo test --target=x86_64-unknown-linux-gnu even fails to compile because of it still tries to use 32-bit assembler sources.

Failures on Debian 32-bit should be tracked by separate issue.

What did the compiler said?

vi commented

I already posted in opening comment. Repeating:

v@l:18:06:16:~/src/git/context-rs$ cargo test --target=x86_64-unknown-linux-musl
   Compiling libc v0.1.12
   Compiling winapi v0.2.5
   Compiling kernel32-sys v0.2.1
   Compiling libc v0.2.5
   Compiling context v0.2.0 (file:///mnt/src/git/context-rs)
Build failed, waiting for other jobs to finish...
/home/vi/.cargo/registry/src/github.com-48ad6e4054423464/libc-0.1.12/rust/src/liblibc/lib.rs:81:21: 81:39 warning: lint raw_pointer_derive has been removed: using derive with raw pointers is ok
/home/vi/.cargo/registry/src/github.com-48ad6e4054423464/libc-0.1.12/rust/src/liblibc/lib.rs:81 #![allow(bad_style, raw_pointer_derive)]
                                                                                                                    ^~~~~~~~~~~~~~~~~~
failed to run custom build command for `context v0.2.0 (file:///mnt/src/git/context-rs)`
Process didn't exit successfully: `/mnt/src/git/context-rs/target/debug/build/context-57e573cff2a60ca6/build-script-build` (exit code: 101)
--- stdout
TARGET = Some("x86_64-unknown-linux-musl")
OPT_LEVEL = Some("0")
PROFILE = Some("debug")
TARGET = Some("x86_64-unknown-linux-musl")
debug=true opt-level=0
HOST = Some("i686-unknown-linux-gnu")
TARGET = Some("x86_64-unknown-linux-musl")
TARGET = Some("x86_64-unknown-linux-musl")
HOST = Some("i686-unknown-linux-gnu")
CC_x86_64-unknown-linux-musl = None
CC_x86_64_unknown_linux_musl = None
TARGET_CC = None
CC = None
HOST = Some("i686-unknown-linux-gnu")
TARGET = Some("x86_64-unknown-linux-musl")
HOST = Some("i686-unknown-linux-gnu")
CFLAGS_x86_64-unknown-linux-musl = None
CFLAGS_x86_64_unknown_linux_musl = None
TARGET_CFLAGS = None
CFLAGS = None
running: "musl-gcc" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-m64" "-fPIC" "-static" "-o" "/mnt/src/git/context-rs/target/x86_64-unknown-linux-musl/debug/build/context-57e573cff2a60ca6/out/src/asm/i686/_context.o" "-c" "src/asm/i686/_context.S"
ExitStatus(ExitStatus(256))


command did not execute successfully, got: exit code: 1



--- stderr
src/asm/i686/_context.S: Assembler messages:
src/asm/i686/_context.S:41: Error: invalid instruction suffix for `pop'
src/asm/i686/_context.S:46: Error: invalid instruction suffix for `pop'
src/asm/i686/_context.S:61: Error: operand type mismatch for `push'
src/asm/i686/_context.S:85: Error: invalid instruction suffix for `pop'
src/asm/i686/_context.S:90: Error: invalid instruction suffix for `pop'
src/asm/i686/_context.S:117: Error: operand type mismatch for `push'
thread '<main>' panicked at 'explicit panic', /home/vi/.cargo/registry/src/github.com-48ad6e4054423464/gcc-0.3.21/src/lib.rs:772

Why the hell it chooses i686? Why cfg!(target_arch = "x86") is chosen when you compile your code with a x86_64 rustc????? That's sooooo weird!

vi commented

Maybe because of build.rs is intended to be executed on host, not on target? So it's "target" is the host...

Oh, maybe.. If yes, then this is a bug.

You could manually modify the build.rs file to force let arch = "x86_86";.

vi commented

With the hack in build.rs it builds and crashes on running, maybe not because of context-rs.

v@l:18:15:17:~/src/git/context-rs$ RUST_TEST_THREADS=1 /n/gdb -args /mnt/src/git/context-rs/target/x86_64-unknown-linux-musl/debug/context-d79e0580000076ee
...
(gdb) r
Starting program: /mnt/src/git/context-rs/target/x86_64-unknown-linux-musl/debug/context-d79e0580000076ee 

running 4 tests
test context::test::test_load_save_context ... ok
test context::test::test_swap_context ... ok
test stack::tests::stack_pool_caches ... [New LWP 27512]

Program received signal SIGSEGV, Segmentation fault.
[Switching to LWP 27512]
0x0000000000403384 in core..option..Option$LT$memmap..Mmap$GT$::drop.7461::h79a633e8e981ec11 ()
(gdb) bt 
#0  0x0000000000403384 in core..option..Option$LT$memmap..Mmap$GT$::drop.7461::h79a633e8e981ec11 ()
#1  0x0000000000403376 in stack..Stack::drop.7458::h2db49cfd6387cece ()
#2  0x0000000000405798 in _$u5b$stack..Stack$u5d$::drop.7710::h6575fe2a995eb762 ()
#3  0x0000000000405728 in Box$LT$$u5b$stack..Stack$u5d$$GT$::drop.7707::ha901eb13f9c8098d ()
#4  0x0000000000405828 in context::mem::forget<Box<[context::stack::Stack]>> (t=...) at ../src/libcore/mem.rs:114
#5  0x0000000000405568 in context::slice::hack::into_vec<context::stack::Stack> (b=...) at ../src/libcollections/slice.rs:153
#6  0x0000000000405432 in context::slice::[T]::into_vec (self=...) at ../src/libcollections/slice.rs:866
#7  0x00000000004053e3 in context::stack::StackPool::new () at src/stack.rs:137
#8  0x000000000040820e in context::stack::tests::stack_pool_caches () at src/stack.rs:213
#9  0x0000000000427697 in boxed::F.FnBox$LT$A$GT$::call_box::h8698088245476464600 ()
#10 0x000000000042a00c in sys_common::unwind::try::try_fn::h7381003144368269990 ()
#11 0x000000000044f989 in __rust_try ()
#12 0x000000000044c86c in sys_common::unwind::try::inner_try::h2137c3d23e591d3eWbt ()
#13 0x000000000042a38b in boxed::F.FnBox$LT$A$GT$::call_box::h2959303587060341762 ()
#14 0x00000000004514d4 in sys::thread::Thread::new::thread_start::ha480b79e2123f07cfBx ()
#15 0x000000000048a095 in start ()
#16 0x0000000000000000 in ?? ()
Warning: the current language does not match this frame.
(gdb) 

The same with x86_64-unknown-linux-gnu. Without RUST_TEST_THREADS=1 it crashes even before running a single test because of this.

Please check the latest commit in master branch, it should work for --target.

vi commented

It's i686, not x86.

Modulo this, it does scompile now.

Nope. I saw the output you pasted above is TARGET = Some("x86_64-unknown-linux-musl"), it should be x86_64. The i686 is just for building the correct ASM file path.

vi commented

Without the change, it now fails without --target:

v@l:18:29:29:~/src/git/context-rs$ cargo test
   Compiling context v0.2.0 (file:///mnt/src/git/context-rs)
failed to run custom build command for `context v0.2.0 (file:///mnt/src/git/context-rs)`
Process didn't exit successfully: `/mnt/src/git/context-rs/target/debug/build/context-57e573cff2a60ca6/build-script-build` (exit code: 101)
--- stderr
thread '<main>' panicked at 'Unsupported architecture: i686-unknown-linux-gnu', build.rs:20

Ah .... Ok, I see. Let me fix it.

vi commented

It you also support old good i386/i486, you can also add them (I saw unofficial Rust versions for them).

I can't sure it is work in i386 and i486. But I already added in the build.rs.