0

I have a packet forwarding application that is mostly working quite well. There is a gtk3 foreach loop that runs every 2 seconds to update channel forwarding statistics in the treeview. To save resources this only runs when the treeview window has the focus.

MainListStore.ForEach(func(tmodel *gtk.TreeModel, path *gtk.TreePath, iterfe *gtk.TreeIter) bool {
// get the channel no
value, _ := tmodel.GetValue(iterfe, MCOL_INPORT)
goValue, _ := value.GoValue()
key := goValue.(int)
// copy stats to liststore
Mutex.Lock()
err := MainListStore.Set(iterfe,
[]int{MCOL_STATPIX, MCOL_STATINT, MCOL_SPDIN, MCOL_SPDOUT},
[]interface{}{Pixes[Statmap[key][0]], Statmap[key][0], Statmap[key][1], Statmap[key][2]})
Mutex.Unlock()
if err != nil {
Logit.Printf("Error: error updating stats chan %s, %v", key, err)
}
return false // keep iterating
})

1: bad pointer crash. I kept this process running for some time and eventually got a crash:

runtime: bad pointer in frame github.com/gotk3/gotk3/gtk.(*TreeModel).ForEach.func1 at 0xc0007df378: 0x2

fatal error: invalid pointer found on stack

My best guess is that between starting the loop and setting values in the liststore, the Treeiter became invalid.

Any suggestions as to what went wrong and how to avoid it would be appreciated.

Is there a way to streamline getting the int key from treemodel? Rather than declaring a *gtk.value, then a govalue interface then the int? Most of which presumably end up on the heap, which brings me to:

  1. Memory use. When this loop is not running, the program runs with about 25MB of RAM. When the loop does run, memory in use very slowly increases, which is probably unavoidable, the interesting thing is that when the window is returned to the background and the loop no longer runs, go does not release the extra memory, it continues to run with whatever the new level is. It would be nice if it could slowly release the memory again.

Thanks for any expert advice!

5
  • 1
    The error doesn't look like its something you or I should take care of, it's probably best to issue a full bug report on gtk3 binding you use. Commented Oct 15, 2024 at 4:41
  • ok, thanks. @Volker. The program has been in use for a few weeks with this update loop only running when in foreground. It was left in the foreground for a day or two and memory in use built up to about 200MB, but otherwise without problems. I wanted to stress test it and made the update loop run all the time and now it keeps crashing with the lost pointer. I'll get onto the gotk3 github. Commented Oct 15, 2024 at 4:58
  • 1
    Something has corrupted the memory, so the easiest thing to do first is check your code with the race detector. Chances are though that it's an error in the gtk3 bindings, or maybe an error using those bindings. If you've followed the documentation closely, then file and issue with that project. Commented Oct 15, 2024 at 11:50
  • I'm pretty sure that the problem is due to interference between the Go garbage collector trying to tidy up a stack and the gtk3 process: runtime stack: runtime.throw({0x140273ed4?, 0x14039bd80?}) C:/Program Files/Go/src/runtime/panic.go:1067 +0x4d fp=0x5ff6d0 sp=0x5ff6a0 pc=0x14006b00d runtime.adjustpointers(0x5ff7f8?, 0x5ff790, 0x1400583c5?, {0x5ff7f8?, 0x140371f00?}) C:/Program Files/Go/src/runtime/stack.go:640 +0x1ad fp=0x5ff730 sp=0x5ff6d0 pc=0x14004eeed etc. I need to work out how to protect this loop from the GC. Commented Oct 25, 2024 at 22:17
  • I think I was getting into trouble because I did not initialise the glib.Value: func ValueInit(t Type) (*Value, error) The program is very stable now, but still chews up memory. Commented Jul 1 at 5:19

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.