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

unreachable triggered by Runtime::block_on and block_on_all when future panics! #1153

Closed
FSMaxB opened this issue Jun 16, 2019 · 3 comments
Closed

Comments

@FSMaxB
Copy link
Contributor

FSMaxB commented Jun 16, 2019

Version

tokio 0.1.21 (also latest master as of now)

Platform

Linux hostname 5.1.9-arch1-1-ARCH #1 SMP PREEMPT Tue Jun 11 16:18:09 UTC 2019 x86_64 GNU/Linux

Description

When running a future that panics on a runtime with block_on or block_on_all, it will trigger an unreachable macro.

It is documented behavior, that those functions panic if the provided future panics, but it shouldn't panic with unreachable since that code is clearly not unreachable.

The bug is here:

pub fn block_on<F, R, E>(&self, future: F) -> Result<R, E>
where
F: Send + 'static + Future<Item = R, Error = E>,
R: Send + 'static,
E: Send + 'static,
{
let mut entered = enter().expect("nested block_on");
let (tx, rx) = futures::sync::oneshot::channel();
self.spawn(future.then(move |r| tx.send(r).map_err(|_| unreachable!())));
entered.block_on(rx).unwrap()
}

pub fn block_on_all<F, R, E>(self, future: F) -> Result<R, E>
where
F: Send + 'static + Future<Item = R, Error = E>,
R: Send + 'static,
E: Send + 'static,
{
let mut entered = enter().expect("nested block_on_all");
let (tx, rx) = futures::sync::oneshot::channel();
self.spawn(future.then(move |r| tx.send(r).map_err(|_| unreachable!())));
let block = rx
.map_err(|_| unreachable!())
.and_then(move |r| {
self.shutdown_on_idle()
.map(move |()| r)
});
entered.block_on(block).unwrap()
}

The unreachable macro should be replaced with something like panic!("The provided future paniced") or something like that.

Code to reproduce:

use futures::prelude::*;

fn main() {
    let runtime = tokio::runtime::Runtime::new().unwrap();
    let future = futures::future::ok::<_,String>(())
        .map(|_| panic!());
    runtime.block_on_all(future).unwrap();
}

Or the same with block_on instead of block_on_all.

The unreachable get's triggered because tx.send errored because the receiving end of the oneshot channel was dropped because of the panic btw.

@carllerche
Copy link
Member

Makes sense to me. Would you be able to provide a PR to update the panic message? Thanks.

@FSMaxB
Copy link
Contributor Author

FSMaxB commented Jun 20, 2019

#1166

@tobz
Copy link
Member

tobz commented Jun 21, 2019

This was fixed in #1166. Thanks again for reporting/fixing it. :)

@tobz tobz closed this as completed Jun 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants