Cargo fails to build with illegal hardware instruction when mongodb is specified as dependecy

Hi,
I am trying to compile my app on termux(Android) but cargo fails to build/check and stops with illegal hardware instruction

> cargo run         
    Updating crates.io index
zsh: illegal hardware instruction  cargo run

I only have MongoDB as a dependency in Cargo.toml and hello world in main.rs and it works on my x86_64 Linux. if I comment out the MongoDB as a dependency then everything works. Why and how does this happen? it didn't even download MongoDB so why commenting out it works?

$ tree
.
├── Cargo.toml
└── src
└── main.rs
1 directory, 2 files

Cargo.toml

[package]
name = "testapp"
version = "0.1.0"
authors = ["WhyAmI"]
edition = "2018"

[dependencies]
mongodb = { version = "1.*", features = ["tokio-runtime"] }

src/main.rs

fn main() {
     println!("hello termux");
}

Where did you get rustc and cargo from? AFAIK there's separate, non-official build specifically for termux.

I installed it from official repository like this

apt install rust

Its working fine with other crates

Try adding a couple of other dependencies, and simultaneously turning off the MongoDB one. Does the illegal instruction error occur with those?

Sounds to me like MongoDB has done some dubious things in their code base. You could try scanning their GitHub repo for asm code. If that were found, I'd say it's time to let go of MongoDB in favor of a more robust solution.

I tried this

[package]
name = "examer"
version = "0.1.0"
authors = ["WhyAmI"]
edition = "2018"

[dependencies]
tokio = { version = "0.2", features = ["full"] }
lazy_static = "1"
clap = "2.*"
futures = { version = "0.3", default-features = false, features = ["alloc"] }
futures-util = "0.3"
async-tungstenite = { version = "*", features= ["tokio-runtime"] }
# mongodb =  { version = "1.*", features = ["tokio-runtime"] }
pbkdf2 = "0.2"
serde = { version = "1.0", features = ["derive", "rc"] }
serde_cbor = "0.11"
derive_builder = "0.9.0"
serde_derive = "1.0"

and it works

So when cargo searches for packages, it executes asm code ?

Honestly I don't know. I merely assume cargo uses the same mechanism for all crates.
If that assumption holds, then it's fairly easy to infer that if one crate works and another doesn't, then the issue is with the crate, not the common mechanism.

mongodb crate itself doesn't have build.rs, so it's not running native code at build time. It could be caused by some of its dependencies. Try building deps from cargo tree to find which crate causes it.

Alternatively, try running cargo under a debugger to see where is the offending instruction.

1 Like

Is it an actual illegal instruction? I've seen that signal when panic-ing inside a drop() implementation in my code that was run inside a tokio test. Didn't spend any time investigating what was going on, I fixed the panic, so unfortunately I can't really help here.

1 Like

I dont thing build.rs has anything to do with it cause its not downloading anything.

cargo tree gives the same error Illegal instruction

I also tried to run cargo run with gdb but I didn't find any useful info.

> gdb -quiet -args cargo build
Reading symbols from cargo...
(No debugging symbols found in cargo)
(gdb) set detach-on-fork off
(gdb) r
Starting program: /data/data/com.termux/files/usr/bin/cargo build

Program received signal SIGILL, Illegal instruction.
0xf743d346 in ?? () from /data/data/com.termux/files/usr/lib/libcrypto.so.1.1
(gdb) c
Continuing.
    Updating crates.io index
[New LWP 20765]
[LWP 20765 exited]

Thread 1 "cargo" received signal SIGILL, Illegal instruction.
0xaac542a8 in ?? ()
(gdb) c
Continuing.
[New LWP 20771]
[New LWP 20772]
[LWP 20772 exited]
[LWP 20771 exited]

Thread 1 "cargo" received signal SIGILL, Illegal instruction.
0xaac542a8 in ?? ()
(gdb) c
Continuing.

Program terminated with signal SIGILL, Illegal instruction.
The program no longer exists.

After googling, I found that Illegal instruction in libcrypto is normal and safe to continue but ... there is still Illegal instruction

If cargo tree crashes, then it has nothing to do with mongodb.

Both probably want to fetch some new packages, and need TLS for that, and it looks like OpenSSL on your system is busted.

"Illegal instruction" is not normal, and it's absolutely not safe to continue. In the best case it's caused by code compiled for a newer CPU instruction set, but more often it's caused by failed assertions or ABI incompatibilities or memory corruption that caused program start executing garbage.

Try reinstalling OpenSSL and Cargo/Rust.

2 Likes

It downloaded other packages without problem.

https://www.raspberrypi.org/forums/viewtopic.php?t=185133#p1170492

> gdb -quiet -args cargo run
Reading symbols from cargo...
(No debugging symbols found in cargo)
(gdb) r
Starting program: /data/data/com.termux/files/usr/bin/cargo run

Program received signal SIGILL, Illegal instruction.
0xf74b9346 in ?? () from /data/data/com.termux/files/usr/lib/libcrypto.so.1.1
(gdb) c
Continuing.
[Detaching after fork from child process 31527]
[Detaching after fork from child process 31528]
[Detaching after fork from child process 31532]
    Updating crates.io index
[New LWP 31644]crate                                                                                                                                                                                                                       
[LWP 31644 exited]
[New LWP 31649]
[LWP 31649 exited]
  Downloaded lazy_static v1.4.0
  Downloaded 1 crate (10.4 KB) in 4.02s
[New LWP 31651]
[New LWP 31652]
[LWP 31652 exited]                                                       ] 0/2: lazy_static                                                                                                                                                
[New LWP 31653]
    Finished dev [unoptimized + debuginfo] target(s) in 1m 02s[LWP 31653 exited]


Thread 4 "cargo" received signal SIGUSR1, User defined signal 1.

I don't wanna switch db cause it looks like only mongodb driver for rust is stable with 1.0 release with async/await. Looks like I have to compile cargo from source with debug symbols to get to the bottom of this mystery

Looks like i'm caught in loop

I need cargo to build cargo and when I try to build cargo on termux, i get illegal hardware instruction

> cargo build        
    Updating crates.io index
zsh: illegal hardware instruction  cargo build

Okay, that's a hacky hack I haven't thought of :slight_smile:

I have cross compiled cargo for android linux from desktop linux and copied it to termux's home and gives better information than illegal hardware instruction

> cargo --version
cargo 1.45.1

> ../fromlaptop/cargo --version
cargo 1.45.1

> CARGO_HTTP_DEBUG=true ../fromlaptop/cargo build
    Updating crates.io index
warning: spurious network error (2 tries remaining): [77] Problem with the SSL CA cert (path? access rights?); class=Net (12)
warning: spurious network error (1 tries remaining): [77] Problem with the SSL CA cert (path? access rights?); class=Net (12)
error: failed to get `clap` as a dependency of package `examer v0.1.0 (/data/data/com.termux/files/home/examer)`

Caused by:
  failed to load source for dependency `clap`

Caused by:
  Unable to update registry `https://github.com/rust-lang/crates.io-index`

Caused by:
  failed to fetch `https://github.com/rust-lang/crates.io-index`

Caused by:
  [77] Problem with the SSL CA cert (path? access rights?); class=Net (12)

EDIT: Sorry, now every crate is giving the same error
I was getting ssl errors while buidling cargo so I added

[target.armv7-linux-androideabi.dependencies]
openssl = { version = "*", features = ["vendored"] }

to cargo's Cargo.toml

looks like features = ["vendored"] did not the trick

> strace ../fromlaptop/cargo build 2>&1 | grep ssl 
fstatat64(AT_FDCWD, "/var/ssl", 0xff925620, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/share/ssl", 0xff925620, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/local/ssl", 0xff925620, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/local/openssl", 0xff925620, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/lib/ssl", 0xff925620, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/ssl", 0xff925620, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/etc/openssl", 0xff925620, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/etc/ssl", 0xff925620, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/boot/system/data/ssl", 0xff925598, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/var/ssl", 0xff915cc8, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/share/ssl", 0xff915cc8, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/local/ssl", 0xff915cc8, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/local/openssl", 0xff915cc8, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/lib/ssl", 0xff915cc8, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/ssl", 0xff915cc8, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/etc/openssl", 0xff915cc8, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/etc/ssl", 0xff915cc8, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/boot/system/data/ssl", 0xff915c40, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/var/ssl", 0xff916168, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/share/ssl", 0xff916168, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/local/ssl", 0xff916168, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/local/openssl", 0xff916168, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/lib/ssl", 0xff916168, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/usr/ssl", 0xff916168, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/etc/openssl", 0xff916168, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/etc/ssl", 0xff916168, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/boot/system/data/ssl", 0xff9160e0, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/home/noone/cargo/target/armv7-linux-androideabi/debug/build/openssl-sys-29ad677bdf0bcbe8/out/openssl-build/install/ssl/certs/38ae8eda.0", 0xff915430, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/home/noone/cargo/target/armv7-linux-androideabi/debug/build/openssl-sys-29ad677bdf0bcbe8/out/openssl-build/install/ssl/certs/244b5494.0", 0xff915430, 0) = -1 ENOENT (No such file or directory)
fstatat64(AT_FDCWD, "/home/noone/cargo/target/armv7-linux-androideabi/debug/build/openssl-sys-29ad677bdf0bcbe8/out/openssl-build/install/ssl/certs/244b5494.0", 0xff915430, 0) = -1 ENOENT (No such file or directory)

gdb SIGILL in libcrypto.so is normal on ARM. It hooks the signal then executes a few instructions to see if they are available or not (ARM does not have an user-space instruction to report available instruction sets like x86). If you run it in a debugger, however, it will stop there. You can ignore it and continue the program.

This is very likely not the actual problem you're seeing.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.