Skip to content

Instantly share code, notes, and snippets.

@tiif
Last active September 2, 2024 07:47
Show Gist options
  • Save tiif/3e08ba6e8cfb1d078e6155410108ae48 to your computer and use it in GitHub Desktop.
Save tiif/3e08ba6e8cfb1d078e6155410108ae48 to your computer and use it in GitHub Desktop.
GSoC 2024: Tokio async support in Miri

Final Report

Contributor: Tiffany Pek Yuan (@tiif)

Mentor: Oli Scherer (@oli-obk)

Project: Tokio async support in Miri

Organization: The Rust Foundation

Overview

Miri is an Undefined Behavior detection tool for Rust. Currently, the support for Tokio async in Miri is minimal as there are certain system calls that have not been handled by Miri (tracked under issue #602). For instance, when Miri runs the code below:

use tokio::fs::File;
use tokio::io::{self, AsyncReadExt};

#[tokio::main]
async fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt").await?;
    let mut buffer = [0; 10];

    // read up to 10 bytes
    let n = f.read(&mut buffer[..]).await?;

    println!("The bytes: {:?}", &buffer[..n]);
    Ok(())
}

The error below will be thrown:

error: unsupported operation: returning ready events from epoll_wait is not yet implemented
   --> /home/byt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/mio-0.8.11/src/sys/unix
      /selector/epoll.rs:97:9
    |
97  | /         syscall!(epoll_wait(
98  | |             self.ep,
99  | |             events.as_mut_ptr(),
100 | |             events.capacity() as i32,
101 | |             timeout,
102 | |         ))
    | |__________^ returning ready events from epoll_wait is not yet implemented
    |
    = help: this is likely not a bug in the program; it indicates that the program 
    performed an operation that the interpreter does not support
    = note: BACKTRACE on thread `tokio-runtime-w`:
    = note: inside `mio::sys::unix::selector::epoll::Selector::select` at 
    /home/byt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/mio-0.8.11/src
    /sys/unix/mod.rs:7:28: 7:49

This project aims to provide support for tokio async in Miri by providing full epoll shim implementation.

Motivation

Miri is typically used in library code where unsafe Rust is used to minimize the risk of having Undefined Behaviour. Enable tokio to be tested with Miri will allow Miri to be utilized in async Rust ecosystem, ensuring greater reliability and stability.

What work was done

We first started with emulating socketpair and eventfd, so epoll can have some target file description to wait on. The related PRs are:

Then we started to emulate epoll by providing implementation for epoll_create1, epoll_ctl and epoll_wait. The related PRs are:

After the epoll PR landed, we found some minor bugs in the implementation, so these PRs are bug fixes and minor enhancement:

Lastly, I added support for blocking epoll:

Then I realised tokio io API started to pass, so I added these tests:

Sometimes I'd like to work on something else to take a break from the syscall implementation, so here are some random PRs that I worked on:

All of the PRs listed above are merged.

Current status of the project

Currently, in the master branch of miri, awaiting on file operation like the code below would run successfully:

    let mut file = File::create(&path).await?;
    file.write(b"some bytes").await?;

Awaiting on mpsc channel would also work:

    let (tx, mut rx) = mpsc::channel(32);
    
    tokio::spawn(async move {
        tx.send("sending from handle").await.unwrap();
    });

The change is now landed on nightly rustc, feel free to test it out!

Ongoing / Future work

I am currently adding blocking support to eventfd and socketpair. I might also work on supporting some other tokio API in future.

Acknowledgement

I would like to thank @oli-obk for being a wonderful mentor who is extremely helpful and pleasurable to work with, @RalfJung for constantly giving good suggestions, Jakub Beránek for making Rust GSoC possible and ensuring everything ran smoothly, and to everyone else who helped along the way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment