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

Dropped non-sync value reported as living until the end of scope #104442

Closed
axos88 opened this issue Nov 15, 2022 · 1 comment
Closed

Dropped non-sync value reported as living until the end of scope #104442

axos88 opened this issue Nov 15, 2022 · 1 comment
Labels
C-bug Category: This is a bug.

Comments

@axos88
Copy link

axos88 commented Nov 15, 2022

    mem::drop(ipptr);
    mem::drop(iphdr);

I tried this code:

#[derive(Debug)]
#[repr(packed)]
//
struct IpHeader {
    version_and_header_len: u8,
    tos: u8,
    tot_len: [u8; 2],
    identification: [u8; 2],
    flags_fragment_offset: [u8; 2],
    ttl: u8,
    protocol: u8,
    checksum: [u8; 2],
    source_address: [u8; 4],
    destination_address: [u8; 4]
}

    pub async fn read(&mut self) -> Result<Vec<u8>, std::io::Error> {
        let mut packet = Vec::with_capacity(1500);

        if AsyncReadExt::take(&mut self.tcp, 20).read_to_end(&mut packet).await? < 20 {
            Err(std::io::Error::new(ErrorKind::InvalidInput, "IP Packet header too short"))?
        };

        info!("HDR = {:X?}", packet);

        let ipptr = packet.as_ptr() as *const IpHeader;

        let iphdr: &IpHeader = unsafe { &*ipptr };

        info!("IP HDR [{}] = {:X?}", mem::size_of_val(iphdr), iphdr);

        let tot_len: u64 = iphdr.tot_len[0] as u64 * 256 + iphdr.tot_len[1] as u64;

        mem::drop(ipptr);
        mem::drop(iphdr);

        if AsyncReadExt::take(&mut self.tcp, tot_len - 20).read_to_end(&mut packet).await? < tot_len - 20 {
            Err(std::io::Error::new(ErrorKind::InvalidInput, "IP Packet data too short"))?
        }

        info!("FULL PACKET = {:X?}", packet);

        packet.shrink_to_fit();

        return Ok(packet);
    }

I expected to see this happen: compiles, the futurue should be Send, as the pointer is dropped before the call to await

Instead, this happened:

error: future cannot be sent between threads safely
   --> src/main.rs:18:22
    |
18  |           tokio::spawn(async move {
    |  ______________________^
19  | |             handshake(&mut socket).await;
20  | |             process(socket).await;
21  | |         });
    | |_________^ future created by async block is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const IpHeader`
note: future is not `Send` as this value is used across an await
   --> src/packet_stream.rs:53:84
    |
42  |         let ipptr = packet.as_ptr() as *const IpHeader;
    |             ----- has type `*const IpHeader` which is not `Send`
...
53  |         if AsyncReadExt::take(&mut self.tcp, tot_len - 20).read_to_end(&mut packet).await? < (tot_len - 20) as usize {
    |                                                                                    ^^^^^^ await occurs here, with `ipptr` maybe used later
...
62  |     }
    |     - `ipptr` is later dropped here
note: required by a bound in `tokio::spawn`
   --> /home/akos/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.2/src/task/spawn.rs:127:21
    |
127 |         T: Future + Send + 'static,
    |                     ^^^^ required by this bound in `tokio::spawn`


Meta

rustc --version --verbose:

rustc 1.66.0-nightly (57f097ea2 2022-10-01)
binary: rustc
commit-hash: 57f097ea25f2c05f424fc9b9dc50dbd6d399845c
commit-date: 2022-10-01
host: x86_64-unknown-linux-gnu
release: 1.66.0-nightly
LLVM version: 15.0.2

@dtolnay
Copy link
Member

dtolnay commented Nov 25, 2022

Closing in favor of #104883 which has a more minimized compilable repro.

@dtolnay dtolnay closed this as completed Nov 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

2 participants