Runtime crash double free or corruption (out) Aborted

⚓ Rust    📅 2025-09-11    👤 surdeus    👁️ 9      

surdeus

Warning

This post was published 63 days ago. The information described in this article may have changed.

I try to create benchmarking tool, but I keep getting a crash with a message like this

double free or corruption (out) Aborted

Does anyone know why I get double free or corruption?

Here is all the error messages:

Here is my code:

use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Instant;
use tokio::sync::Semaphore;
use tokio::time::Duration;

type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;

#[tokio::main]
async fn main() -> Result<()> {
    let url = "http://127.0.0.1:8080/4";
    
    let start = Instant::now();
    let success = Arc::new(AtomicUsize::new(0));
    let total = Arc::new(AtomicUsize::new(0));
    
    let semaphore = Arc::new(Semaphore::new(200));
    
    let client = reqwest::Client::builder()
        .pool_max_idle_per_host(200)  
        .pool_idle_timeout(Duration::from_secs(60))
        .timeout(Duration::from_secs(2))
        .build()?;
    
    let client = Arc::new(client);

    let mut spawn_count = 0;
    
    while start.elapsed().as_secs() < 15 {
        let client_clone = client.clone();
        let success_clone = success.clone();
        let total_clone = total.clone();
        let sem_clone = semaphore.clone();
        
        tokio::spawn(async move {
            let _permit = sem_clone.acquire().await.unwrap();
            
            match client_clone.get(url).send().await {
                Ok(response) if response.status().is_success() => {
                    success_clone.fetch_add(1, Ordering::Relaxed);
                }
                _ => {}
            }
            
            total_clone.fetch_add(1, Ordering::Relaxed);
        });
        
        spawn_count += 1;
    }

    let spawn_time = start.elapsed();

    while start.elapsed().as_secs() < 20 {
        let current_total = total.load(Ordering::Relaxed);
        if current_total >= spawn_count {
            break;
        }
        tokio::task::yield_now().await;
    }

    let final_success = success.load(Ordering::Relaxed);
    let final_total = total.load(Ordering::Relaxed);
    let final_time = start.elapsed();
    
    println!("Spawned: {} requests in {:.3}s", spawn_count, spawn_time.as_secs_f64());
    println!("Completed: {} requests", final_total);
    println!("Success: {}/{} ({:.2}%)", 
        final_success, final_total, 
        (final_success as f64 / final_total.max(1) as f64) * 100.0);
    println!("Total time: {:.3}s", final_time.as_secs_f64());
    println!("RPS: {:.0}", final_total as f64 / final_time.as_secs_f64());

    Ok(())
}

3 posts - 2 participants

Read full topic

🏷️ Rust_feed