jwharm/java-gi

Fatal Error : C [libgio-2.0.so.0+0xcb1b5] g_list_model_get_n_items+0x25

Closed this issue · 8 comments

Hi.
I get this error : C [libgio-2.0.so.0+0xcb1b5] g_list_model_get_n_items+0x25 when create a columnview with SelectionModel (single,multi).
how fix it ?

Please add the source code.

ok i will

fun main (args : Array<String>) {
    val app = Application("co.ex.test", ApplicationFlags.DEFAULT_FLAGS)
    app.onActivate {
        val window = ApplicationWindow(app).apply {
            val scrolledWindow = ScrolledWindow().apply {
                halign = Align.FILL
                hexpand = true
            }
            val columnGen = makeColumn()

            makeList().sortedBy { it.name }.forEach {
                columnGen.first.append(it)
            }
            scrolledWindow.child = columnGen.second
            child = scrolledWindow
        }
        window.present()
    }
    app.run(args)
}

private fun makeColumn () : Pair<ListStore, ColumnView>{

    val nameFac = SignalListItemFactory().apply {
        onSetup { obj ->
            val row = obj as ColumnViewCell
            row.child = Box(Orientation.HORIZONTAL,0).apply {
                marginEnd = 8
                marginBottom = 8
                marginStart = 8
                marginTop = 8
                halign = Align.FILL
                hexpand = true

                val icon = Image.fromIconName("folder")

                val label = Label("").apply {
                    marginStart = 12

                    halign = Align.START
                    hexpand = true
                }

                append(icon)
                append(label)
            }
        }
        onBind { obj ->
            val row = obj as ColumnViewCell
            val child = row.child as Box
            val label = child.lastChild as Label
            val model = obj.item as FileModel
            label.label = model.name
        }
    }
    val sizeFac = SignalListItemFactory().apply {
        onSetup { obj ->
            val row = obj as ColumnViewCell
            row.child = Label("").apply {
                marginEnd = 8
                marginBottom = 8
                marginStart = 8
                marginTop = 8
                halign = Align.START
                hexpand = true
            }
        }
        onBind { obj ->
            val row = obj as ColumnViewCell
            val child = row.child as Label
            val model = obj.item as FileModel
            child.label = model.size.formatToSizeFile()
        }
    }

    val store = ListStore(FileModel.gType)

    val columnView = ColumnView(MultiSelection(store)).apply {
        halign = Align.FILL
        hexpand = true
    }

    val nameColumn = ColumnViewColumn("Name",nameFac).apply {
        expand = true
    }
    val sizeColumn = ColumnViewColumn("Size",sizeFac).apply {
        fixedWidth = -1
    }
    columnView.appendColumn(nameColumn)
    columnView.appendColumn(sizeColumn)

    return Pair(store,columnView)
}

private fun makeList () : List<FileModel> {
    val file = File("/your/home/dir")
    val out = mutableListOf<FileModel>()
    file.listFiles()?.forEach {
        out.add(FileModel.create().apply {
            name = it.name
            size = it.length()
            path = it.absolutePath
            modified = it.lastModified()
        })
    }
    return out
}

class FileModel(address: MemorySegment?) : GObject(address) {
    companion object {
        var gType: Type = Types.register<FileModel, ObjectClass>(FileModel::class.java)
        fun create(): FileModel {
            return newInstance(gType)
        }
    }
    var name : String = ""
    var path : String = ""
    var size : Long = 0
    var modified : Long = 0

}

This is an example of my code.
To see the problem, select an item in list and move in the list with the up and down arrow keys on keyboard. After a few moments you will see the error

I can't reproduce the error, but I've seen a similar error before. I'm 99% sure it's related to garbage collection of the ListStore.

Looking at the main function and the app.onActivate callback, you see that the ListStore is constructed (as a part of the columnGen Pair) and then the window is presented. Past that point, the ListStore instance is not used anymore in the kotlin code. It's still used by native code, but the JVM is not aware of that. So when after a while the Garbage Collector runs, it destroys the ListStore instance.

If you put the ListStore (or in your case, the columnGen variable) in a public field, the JVM should keep it alive, and the crash should disappear.

If you put the ListStore (or in your case, the columnGen variable) in a public field, the JVM should keep it alive, and the crash should disappear.

I will test this

@jwharm
Yes, it was done!
The problem was the JVM garbage collector. thank you 👍.

@SudoDios This turned out to be a bug in java-gi after all. It will be fixed in the next release.

@jwharm Really?!
How interesting.