Description
I’m seeing a heap corruption crash when using glommio::channels::spsc_queue from multiple producer and consumer threads.
The code only uses safe Rust and the public glommio::channels::spsc_queue API, but at runtime it fails with:
Avvio demo Glommio Multi-Thread...
malloc(): chunk size mismatch in fastbin
malloc(): chunk size mismatch in fastbin
Aborted (core dumped) cargo run
This looks like memory corruption / unsoundness in safe code.
I realize this is an SPSC queue and that my sample intentionally uses multiple producers and multiple consumers, but since the API is fully safe, it shouldn’t be possible to trigger heap corruption (ideally the type system or runtime checks would prevent this usage, or at worst it should fail cleanly without UB).
Environment
- Glommio version:
0.9.0 (from github)
- Rust version:
rustc 1.xx.x (stable)
- OS: Linux x86_64 Fedora
- Build:
cargo run --release and cargo run both affected
Minimal reproducible example
use std::error::Error;
use glommio::channels::spsc_queue;
fn main() -> Result<(), Box<dyn Error>> {
println!("Avvio demo Glommio Multi-Thread...");
let (sender, mut receiver) = spsc_queue::make::<String>(4096);
let mut producers = Vec::new();
let mut consumers = Vec::new();
// 2 producers
for i in 0..2 {
let sender = sender.clone();
producers.push(std::thread::spawn(move || {
for j in 0..500_000 {
let msg = format!("Messaggio {} dal produttore {}\n", j, i);
// ignoring the return value for simplicity
let _ = sender.try_push(msg);
}
}));
}
// 2 consumers
for _ in 0..2 {
let receiver = receiver.clone();
consumers.push(std::thread::spawn(move || {
for _ in 0..500_000 {
let _ = receiver.try_pop();
}
}));
}
for producer in producers {
producer.join().unwrap();
}
for consumer in consumers {
consumer.join().unwrap();
}
Ok(())
}
Running this with cargo run produces:
Avvio demo Glommio Multi-Thread...
malloc(): chunk size mismatch in fastbin
malloc(): chunk size mismatch in fastbin
Aborted (core dumped) cargo run
Expected behavior
Even if using spsc_queue in a way that violates its logical “single producer / single consumer” design, the use of safe APIs should not result in undefined behavior or heap corruption.
Ideally one of the following would happen instead:
- The type system prevents this misuse (e.g.
Producer / Consumer not being Clone, or being more constrained), or
- There are documented guarantees that misusing the queue can cause UB, or
- The queue detects this situation and fails in a defined way (panic, error, etc.), rather than corrupting memory.
Actual behavior
-
Program prints Avvio demo Glommio Multi-Thread...
-
Then glibc reports:
malloc(): chunk size mismatch in fastbin
malloc(): chunk size mismatch in fastbin
Aborted (core dumped)
-
This suggests memory corruption happening internally, triggered only through safe Producer::try_push and Consumer::try_pop calls.
Additional notes
Producer<T> and Consumer<T> are Send but !Sync, and they are Clone. This allows creating multiple cloned producers/consumers that operate concurrently on the same underlying queue from different threads.
- The module name
spsc_queue suggests single-producer/single-consumer behavior, but the current API surface (especially Clone + Send) makes it easy to use it in multi-producer/multi-consumer scenarios without any compiler errors or warnings.
- Even if this usage is considered invalid, the fact that it leads to heap corruption in safe Rust feels like at least a documentation or soundness issue.
If this usage is explicitly unsupported and considered undefined behavior, it might be helpful to:
- Clarify that in the documentation for
spsc_queue::make, Producer, and Consumer, and/or
- Tighten the API (e.g. remove
Clone or add runtime checks) so that this pattern doesn’t compile or at least doesn’t lead to memory corruption.
Description
I’m seeing a heap corruption crash when using
glommio::channels::spsc_queuefrom multiple producer and consumer threads.The code only uses safe Rust and the public
glommio::channels::spsc_queueAPI, but at runtime it fails with:This looks like memory corruption / unsoundness in safe code.
I realize this is an SPSC queue and that my sample intentionally uses multiple producers and multiple consumers, but since the API is fully safe, it shouldn’t be possible to trigger heap corruption (ideally the type system or runtime checks would prevent this usage, or at worst it should fail cleanly without UB).
Environment
0.9.0(from github)rustc 1.xx.x (stable)cargo run --releaseandcargo runboth affectedMinimal reproducible example
Running this with
cargo runproduces:Expected behavior
Even if using
spsc_queuein a way that violates its logical “single producer / single consumer” design, the use of safe APIs should not result in undefined behavior or heap corruption.Ideally one of the following would happen instead:
Producer/Consumernot beingClone, or being more constrained), orActual behavior
Program prints
Avvio demo Glommio Multi-Thread...Then glibc reports:
This suggests memory corruption happening internally, triggered only through safe
Producer::try_pushandConsumer::try_popcalls.Additional notes
Producer<T>andConsumer<T>areSendbut!Sync, and they areClone. This allows creating multiple cloned producers/consumers that operate concurrently on the same underlying queue from different threads.spsc_queuesuggests single-producer/single-consumer behavior, but the current API surface (especiallyClone+Send) makes it easy to use it in multi-producer/multi-consumer scenarios without any compiler errors or warnings.If this usage is explicitly unsupported and considered undefined behavior, it might be helpful to:
spsc_queue::make,Producer, andConsumer, and/orCloneor add runtime checks) so that this pattern doesn’t compile or at least doesn’t lead to memory corruption.