Skip to content

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

@axos88

Description

@axos88
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions