cpal + dioxus_desktop: eats memory and dies
With latest versions:
cpal = { version = "0.15.2", features=["jack"] }
dioxus = "0.3.2"
dioxus-ssr = "0.3.0"
dioxus-desktop = "0.3.0"
Consider this minimal code:
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{BufferSize, Device, Stream, StreamConfig, SupportedBufferSize};
use std::cmp::max;
fn main() {
let _stream = start_cpal();
loop {}
}
fn start_cpal() -> Stream {
let device = get_device();
let config = get_config(&device);
let stream = device
.build_output_stream(
&config,
move |_: &mut [f32], _: &cpal::OutputCallbackInfo| {},
move |_| {},
None,
)
.unwrap();
stream.play().unwrap();
stream
}
fn get_device() -> Device {
let host_id = cpal::available_hosts()[0];
let host = cpal::host_from_id(host_id).unwrap();
host.default_output_device().unwrap()
}
fn get_config(device: &Device) -> StreamConfig {
let mut supported_configs_range = device.supported_output_configs().unwrap();
let supported_config = supported_configs_range
.next()
.unwrap()
.with_max_sample_rate();
let mut config = supported_config.config();
config.buffer_size = BufferSize::Fixed(get_some_buffer_size(supported_config.buffer_size()));
config
}
fn get_some_buffer_size(spec: &SupportedBufferSize) -> u32 {
match spec {
SupportedBufferSize::Range { min, .. } => max(*min, 64),
SupportedBufferSize::Unknown => 64,
}
}
It works as expected (program runs; nothing happens). I also get sound if I put something in the data callback.
Enter dioxus desktop:
fn main() {
let _stream = start_cpal();
dioxus_desktop::launch(app);
}
use dioxus::prelude::*;
fn app(cx: Scope) -> Element {
cx.render(rsx!("lol"))
}
// .. same code as before
Expected result: cpal still works; Dioxus window shows up.
Actual result: program eats all the memory and the OS kills it. No window shows up.
The start of the spike is where I run the program. It falls back down after a few seconds when the process is killed.
The issue is not with Dioxus alone, because this program works as expected:
fn main() {
dioxus_desktop::launch(app);
}
The problem only occurs when I use cpal and Dioxus in the same program.
I don't know if this is an issue with Dioxus or cpal, and I have no idea where to begin debugging this. Any ideas please?
I'm on Ubuntu 22.04.2 LTS. Lemme know if you need any other details. Thank you!!
Use a heap profiler (like valgrind's massif) to see what code is responsible for the allocations.
Thanks for the suggestion! Unfortunately, I can't seem to get anything out of valgrind.
If I simply run massif, the program still gets killed, and I get no output.
$ valgrind --tool=massif ./target/debug/hello_cpal
==249915== Massif, a heap profiler
==249915== Copyright (C) 2003-2017, and GNU GPL'd, by Nicholas Nethercote
==249915== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==249915== Command: ./target/debug/hello_cpal
==249915==
Killed
I thought of creating a snapshot using gdb before the program is killed. However, as soon as I use continue to actually start the program, gdb becomes unresponsive, and I can't use the monitor snapshot command.
Am I doing this wrong? Sorry I'm new to this valgrind stuff.