Getting "Illegal instruction (core dumped)" on a simple program


#1

Please can anyone help me on the below issue.
I’ve just written my first Rust program which looks like this:

struct timeval {
    tv_sec: i64,
    tv_usec: i64
}

extern {
    fn gettimeofday(tv: &mut timeval) -> i32;
}

fn now() -> i64 {
    let mut tv = timeval { tv_sec: 0, tv_usec: 0 };
    unsafe {
        gettimeofday(&mut tv);
    }
    tv.tv_sec * 1000 + tv.tv_usec / 1000
}

fn main() {
    for x in 0..1 {
        now();
    }
}

Now the problem is that when I compile it and run I get:
Illegal instruction (core dumped)

If I remove the for loop and just call now() function, it works fine.
What am I doing wrong here?

The compiler I’m using:
rustc 1.0.0-nightly (ea8b82e90 2015-03-17) (built 2015-03-18)
Platform:
3.8.0-44-generic #66~precise1-Ubuntu SMP Tue Jul 15 04:01:04 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Many thanks,
Dmitry


#2
  1. You need to mark timespec with #[repr(C)] to tell rust not to mess with the struct’s layout.
  2. gettimeofday takes 2 arguments (where the second is null).

Read: https://doc.rust-lang.org/book/ffi.html

The following works (although the type of the second parameter really should be void but I didn’t feel like importing the libc crate):

use std::ptr;

#[repr(C)]
struct timeval {
    tv_sec: i64,
    tv_usec: i64
}

extern {
    fn gettimeofday(tv: &mut timeval, tzp: *const ()) -> i32;
}

fn now() -> i64 {
    let mut tv = timeval { tv_sec: 0, tv_usec: 0 };
    unsafe {
        gettimeofday(&mut tv, ptr::null());
    }
    tv.tv_sec * 1000 + tv.tv_usec / 1000
}

fn main() {
    for x in 0..1 {
        now();
    }
}

#3

EDIT: Looks like @stebalien beat me to it, and with a better answer; mine is probably wrong. I’ll leave this here anyway…


Hello! And welcome!

Here is my concern:

extern {
    fn gettimeofday(tv: &mut timeval) -> i32;
}

So… you’re declaring that this function will be “externally” implemented. Is that what you meant? Are you linking against some C code? I’m not all that familiar with the Rust FFI, but your code does not include a few features from the example in the Rust Book on FFI.

For example, you don’t have #[link(name = "sys/time")], which I think you might need.

If there’s some missing code in your example (such as where gettimeofday() is coming from), please post that!


#4

Thanks guys for help! It was quite silly of me not to check the exact function signature first. However there is still something not quite right here. The reason why I thought everything was alright with my external function is that it works just fine if executing outside of the for loop. I can call “now” several times from the main function and it works fine and returns expected result. So it must be something specific to the for loop that it makes it crash without the second parameter.


#5

It might be due to some optimizations/inlining or maybe rust constructs stacks differently in a loop. Regardless, calling an external function with the wrong signature is undefined behavior so rust is free to do whatever it wants.