Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't call foreign function: clock_gettime #641

Closed
kpp opened this issue Feb 23, 2019 · 25 comments
Closed

Can't call foreign function: clock_gettime #641

kpp opened this issue Feb 23, 2019 · 25 comments
Labels
A-shims Area: This affects the external function shims C-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement

Comments

@kpp
Copy link

kpp commented Feb 23, 2019

cargo +nightly miri -V # miri 0.1.0 (76138c5 2019-02-17)
rustc -vV # 1.34.0-nightly (146aa60f3 2019-02-18)

How to reproduce:

cd tokio
git log -n1 # commit 4985e0c6084646e0de2a42b361ca897882eff504
$ cargo +nightly miri test
   Compiling tokio v0.1.15 (/home/humbug/tokio)
running 1 test
error[E0080]: constant evaluation error: can't call foreign function: clock_gettime
   --> /home/humbug/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/sys/unix/time.rs:361:13
    |
361 |             libc::clock_gettime(clock, &mut t.t)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function: clock_gettime
    |
    = note: inside call to `std::sys::unix::time::inner::now` at /home/humbug/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/sys/unix/time.rs:275:26
    = note: inside call to `std::sys::unix::time::inner::Instant::now` at /home/humbug/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/time.rs:158:22
    = note: inside call to `std::time::Instant::now` at /home/humbug/tokio/tokio-timer/src/clock/clock.rs:48:17
    = note: inside call to closure at /home/humbug/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/thread/local.rs:300:16
    = note: inside call to `<std::thread::LocalKey<T>><std::cell::Cell<std::option::Option<*const tokio_timer::clock::Clock>>>::try_with::<[closure@DefId(54/1:9 ~ tokio_timer[4753]::clock[0]::clock[0]::now[0]::{{closure}}[0])], std::time::Instant>` at /home/humbug/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/thread/local.rs:246:9
    = note: inside call to `<std::thread::LocalKey<T>><std::cell::Cell<std::option::Option<*const tokio_timer::clock::Clock>>>::with::<[closure@DefId(54/1:9 ~ tokio_timer[4753]::clock[0]::clock[0]::now[0]::{{closure}}[0])], std::time::Instant>` at /home/humbug/tokio/tokio-timer/src/clock/clock.rs:46:5
    = note: inside call to `tokio_timer::clock::now` at /home/humbug/tokio/tokio-timer/src/timeout.rs:128:40
note: inside call to `<tokio_timer::Timeout<T>><futures::Finished<(), ()>>::new` at src/util/future.rs:64:9
   --> src/util/future.rs:64:9
    |
64  |         Timeout::new(self, timeout)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside call to `<futures::Finished<(), ()> as util::future::FutureExt>::timeout` at src/util/future.rs:90:32
   --> src/util/future.rs:90:32
    |
90  |         let timeouted_future = base_future.timeout(Duration::new(0, 0));
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside call to `util::future::test::timeout_polls_at_least_once` at src/util/future.rs:88:5
   --> src/util/future.rs:88:5
    |
88  | /     fn timeout_polls_at_least_once() {
89  | |         let base_future = future::result::<(), ()>(Ok(()));
90  | |         let timeouted_future = base_future.timeout(Duration::new(0, 0));
91  | |         assert!(timeouted_future.wait().is_ok());
92  | |     }
    | |_____^

...
...
...
@bjorn3
Copy link
Member

bjorn3 commented Feb 23, 2019

What value should it return? Always zero (makes timeout impossible), current time (not deterministic) or start with zero and increase every executed statement?

@oli-obk
Copy link
Contributor

oli-obk commented Feb 23, 2019

Even starting with zero and incrementing with every call to clock_gettime counts as "not deterministic", because it will differ from runtime behavior. Before implementing this, we'll need to add a flag to miri that turns nondeterministic behavior off (I think it should be the default). So maybe --deterministic.

@RalfJung
Copy link
Member

Yeah, this is currently outside the range of what Miri is intended to support. We can't do I/O anyway so timeouts would hardly make much sense.

@kpp
Copy link
Author

kpp commented Feb 23, 2019

Yeah but tokio is an important part of Rust ecosystem but it scares me a little bit with its TSAN suppressions file. I would like to have a opportunity to run Tokio tests with miri (even a subset of them).

@RalfJung
Copy link
Member

RalfJung commented Feb 23, 2019

Sure it'd be great if we could run more things in Miri, just some things are much harder to get running than others. ;) Basically, for now the focus is on libraries that are platform-agnostic and do not need to access any but the most basic OS facilities. Even there we still have some gaps, such as the following program:

fn main() {
    let v: [Vec<i32>; 0] = [];
    let c = v.concat();
    assert_eq!(c, []);
}

(This is an instance of #224.)


TSAN suppressions file

Notice that Miri does not support concurrency, and if it did it'd likely not detect data races. So it is not a supplement for TSAN.

Don't get me wrong, I'd love to make Miri test tokio. It's just a lot of work. Don't expect us to implement epoll any time soon...

Does Tokio have a part of the test suite that can run without any I/O? Does that even make sense? That would be the kind of tests that I think you could hope to run in Miri. Another good idea might be to look at the infrastructure crates that tokio relies on, and test those.

@RalfJung RalfJung added A-shims Area: This affects the external function shims C-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement labels Feb 23, 2019
@petrochenkov
Copy link
Contributor

Can't miri execute these on host by dlopening libc and executing clock_gettime via dlsymed pointer, then return the result into the interpreter?
That would cover some basic cases at least.
(I haven't thought this through too much, so there may be obvious blockers.)

@oli-obk
Copy link
Contributor

oli-obk commented Feb 23, 2019

the dlopen scheme is basically what we're considering in #11

The "obvious blockers" are that it's not a priority for @RalfJung and I to spend implementation time on it ;)

@kpp
Copy link
Author

kpp commented Feb 23, 2019

Another good idea might be to look at the infrastructure crates that tokio relies on, and test those.

Thanks! I will try!

@RalfJung
Copy link
Member

Can't miri execute these on host by dlopening libc and executing clock_gettime via dlsymed pointer, then return the result into the interpreter?

Besides the huge implementation complexity, that would also break cross-interpretaion -- currently Miri can execute MIR for any target on any host.

@petrochenkov
Copy link
Contributor

petrochenkov commented Feb 23, 2019

Well, yes, this "semihosting" is supposed to be a separate limited mode, not something that would work on every program in any configuration.

@RalfJung
Copy link
Member

RalfJung commented Apr 9, 2019

With #683 coming up to tackle #653, it might be time to reconsider this.

My position is that we should have a flag like -Zmiri-allow-communication (or -Zmiri-disable-communication, not sure what the default should be) to enable Miri and the outside world to communicate (beyond mere stdout/stderr). This flag would let the outside world affect Miri's execution (through environment variables or getting the current time, and eventually through reading files or whatnot) and vice versa (through creating/writing files and so on). Do you think that would make sense?

@kpp
Copy link
Author

kpp commented Apr 9, 2019

I don't know.

cc @carllerche

@elichai
Copy link
Contributor

elichai commented Aug 26, 2019

I think working on support libstd is an important steeping stone.
even just letting the call through and assuming clock_gettime is fine. is a good start.(non deterministic)

@RalfJung
Copy link
Member

#800 is actually ongoing and we do have -Zmiri-enable-communication these days (I plan to change that to -Zmiri-disable-isolation though).

With that flag set, letting the program access the clock seems fine. Someone just has to implement it. :)

@elichai
Copy link
Contributor

elichai commented Aug 26, 2019

@RalfJung Cool! so I enabled -Zmiri-enable-communication and it seems to work, tough I'm now getting Miri evaluation error: can't call foreign function: stat64 which I'm not sure how it's called

@RalfJung
Copy link
Member

Eh, the clock isn't implemented yet. So enabling communication won't make a difference for that.

Miri evaluation error: can't call foreign function: stat64

Looks like you are doing file system access. That's a lot of shims that someone has to implement. See #923.

@elichai

This comment has been minimized.

@RalfJung

This comment has been minimized.

@elichai

This comment has been minimized.

@RalfJung

This comment has been minimized.

@elichai

This comment has been minimized.

@RalfJung

This comment has been minimized.

@elichai

This comment has been minimized.

bors added a commit that referenced this issue Aug 28, 2019
test that build scripts do not run in Miri

@elichai reported something that sounded a lot like build script running in Miri. But as this test shows, build scripts are not run by Miri, they are run normally.

@elichai are you sure the [env var usage you were referring to](#641 (comment)) was only in a build script? Those shouldn't be affected by Miri flags at all. Is your code available somewhere so that I can try to reproduce?
bors added a commit that referenced this issue Aug 28, 2019
test that build scripts do not run in Miri

@elichai reported something that sounded a lot like build script running in Miri. But as this test shows, build scripts are not run by Miri, they are run normally.

@elichai are you sure the [env var usage you were referring to](#641 (comment)) was only in a build script? Those shouldn't be affected by Miri flags at all. Is your code available somewhere so that I can try to reproduce?
bors added a commit that referenced this issue Aug 28, 2019
test that build scripts do not run in Miri

@elichai reported something that sounded a lot like build script running in Miri. But as this test shows, build scripts are not run by Miri, they are run normally.

@elichai are you sure the [env var usage you were referring to](#641 (comment)) was only in a build script? Those shouldn't be affected by Miri flags at all. Is your code available somewhere so that I can try to reproduce?
@pvdrz
Copy link
Contributor

pvdrz commented Oct 18, 2019

the clock and file shims have already landed on unix and we already have an issue for the windows clock counterpart. I think we can mark this one as solved. Thoughts?

@RalfJung
Copy link
Member

Sounds about right. But when mentioning a PR or issue, please always link to them for future reference. :)

Implementing PR: #975
Windows issue: #997

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-shims Area: This affects the external function shims C-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement
Projects
None yet
Development

No branches or pull requests

7 participants