Skip to content

Gtk4-rs tests freeze on Rust 1.87.0 and newer #149942

@qarmin

Description

@qarmin

Code

Cargo toml

[package]
name = "t"
version = "0.1.0"
edition = "2021"

[dependencies]
gtk4 = "0.10.0"
glib = "0.21.1"
use std::fs;
use gtk4::prelude::*;
mod tests;
fn main() {
    let txt = r##"
      #[gtk4::test]
    fn test_list_store_iterxxxxxx() {
        let columns_types: &[Type] = &[Type::STRING];
        let list_store = gtk4::ListStore::new(columns_types);
        let values = ["a", "b", "c"];
        for v in &values {
            let iter = list_store.append();
            list_store.set(&iter, &[(0, &(*v))]);
        }
        let collected: Vec<String> = list_store.custom_iter().map(|iter| list_store.get::<String>(&iter, 0)).collect();
        assert_eq!(collected, values.iter().map(|s| s.to_string()).collect::<Vec<_>>());
        let empty = gtk4::ListStore::new(&[Type::STRING]);
        let mut it = empty.custom_iter();
        assert!(it.next().is_none());
    }

    "##;

    let mut all = r#"
#[cfg(test)]
mod tests {
    use gtk4::prelude::*;
    use crate::ListStoreIterExt;
use glib::types::Type;
"#.to_string();
    for i in 0..400 {
        all += txt.replace("xxxxxx", &i.to_string()).as_str();
    }

    all += "}\n";
    fs::write("src/tests.rs", all).expect("Unable to write file");
}


pub struct ListStoreIter<'a> {
    list_store: &'a gtk4::ListStore,
    current: Option<gtk4::TreeIter>,
}

impl<'a> ListStoreIter<'a> {
    pub fn new(list_store: &'a gtk4::ListStore) -> Self {
        let current = list_store.iter_first();
        Self { list_store, current }
    }
}

impl<'a> Iterator for ListStoreIter<'a> {
    type Item = gtk4::TreeIter;
    fn next(&mut self) -> Option<Self::Item> {
        match &mut self.current {
            None => None,
            Some(iter) => {
                // dbg!(&iter); // Uncommenting this line, fixes issue
                let result = Some(*iter);
                let next_iter = *iter;
                if self.list_store.iter_next(&next_iter) {
                    self.current = Some(next_iter);
                } else {
                    self.current = None;
                }
                result
            }
        }
    }
}

pub trait ListStoreIterExt {
    fn custom_iter(&self) -> ListStoreIter;
}

impl ListStoreIterExt for gtk4::ListStore {
    fn custom_iter(&self) -> ListStoreIter {
        ListStoreIter::new(self)
    }
}

Project

Rust 1.86.0 executes the tests correctly. Running:

cargo +1.86.0 test --release

finishes as expected:

test tests::tests::test_list_store_iter98 ... ok
test tests::tests::test_list_store_iter99 ... ok
test result: ok. 400 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s

However, Rust 1.87.0 and later freeze during execution and consume an excessive amount of RAM over time when running:

cargo +1.87.0 test --release

Related gtk4-rs issue - gtk-rs/gtk4-rs#2140

This may be caused either by a change in Rust optimizations or by invalid behavior in gtk4-rs that only manifests with newer compiler versions.

I ran the code under AddressSanitizer and Valgrind and found no memory errors, which suggests this is more likely an optimization-related issue rather than a direct memory safety problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-external-bugCategory: issue that is caused by bugs in software beyond our controlE-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions