slowtec / tokio-modbus

A tokio-based modbus library
Apache License 2.0
417 stars 122 forks source link

memory leak in tcp client when repeatedly writing holding register #301

Closed fbrisa closed 7 hours ago

fbrisa commented 4 days ago

Hi, I think I found a memory leak bug:

I have a program that makes 2 holding register writes: first call writes a value second call writes 2 values (problem happens even with more number of values)

if you keep doing that, program will continue to double the ram needed because of this line in src/coded/tcp.rs (line 136) buf.reserve((buf.capacity() - buf_offset) + request_pdu_size + 7);

this happens on every iteration, you will see an initial 8KB usage than 16KB and so on till the program crashes

it does not matter that the server answers, problem will occur eventually

fbrisa commented 3 days ago

Here an example on how to see the error:

it is the tpc client example with a infinite loop, to make the 2 calls:

on my pc crashes at iteration 21 saying:

memory allocation of 34359738368 bytes failed

#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    use tokio_modbus::prelude::*;

    let socket_addr = "127.0.0.1:5502".parse().unwrap();

    let mut ctx = tcp::connect(socket_addr).await?;

    let mut idx=1;
    loop {
        println!("Iteration {}", idx);
        ctx.write_multiple_registers(0x1000, &[1]).await??;
        ctx.write_multiple_registers(0x1000, &[1,2]).await??;

        idx+=1;
    }

    // it will never land here

    println!("Disconnecting");
    ctx.disconnect().await?;

    Ok(())
}
cdbennett commented 1 day ago

It appears this issue was introduced in main with #292, and it seems that it did not affect v0.15.0 or earlier.