Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segmentation fault in python?

I'm creating GUI using gtk3. So that the GUI and operation works together, I make a thread with this code: threading.Thread(target=function).start(). Without threading, everything works well, but the GUI will be freezed. With threading, this error occured:

The first one is Segmentation fault (core dumped)

The second one is *** glibc detected *** python: double free or corruption (!prev): 0x09154320 ***

The third one is Gtk:ERROR:/build/buildd/gtk+3.0-3.4.2/./gtk/gtktextview.c:3726:gtk_text_view_va‌​lidate_onscreen: assertion failed: (priv->onscreen_validated) Aborted (core dumped)

Do you know why did that happens?

EDIT: my code:

GUI.py

from gi.repository import Gtk, Gdk, GLib
import Process
import gobject
import threading

class gui():
def __init__(self):
    self.window = Gtk.Window()
    self.window.connect('delete-event', Gtk.main_quit)

    self.box = Gtk.Box()
    self.window.add(self.box)

    self.label = Gtk.Label('idle')
    self.box.pack_start(self.label, True, True, 0)

    self.progressbar = Gtk.ProgressBar()
    self.box.pack_start(self.progressbar, True, True, 0)

    self.button = Gtk.Button(label='Start')
    self.button.connect('clicked', self.on_button_clicked)
    self.box.pack_start(self.button, True, True, 0)

    self.window.show_all()

    GLib.threads_init()
    Gdk.threads_init()
    Gdk.threads_enter()
    Gtk.main()
    Gdk.threads_leave()

def working1(self):
   self.label.set_text('working1')
   result = Process.heavyworks1()   
   print result
   self.label.set_text('idle')  

def on_button_clicked(self, widget):
    threading.Thread(target=self.working1).start()

if __name__ == '__main__':
    gui = gui()

gui

Process.py

a = 0 x = 'something'

def heavyworks1():
    #global a
    #doing something
    #doing other thing
    #a = something
    #return result

def heavyworks2(param):
     #doing something
    #doing other thing
    #return result
like image 325
user2435611 Avatar asked Mar 23 '23 16:03

user2435611


2 Answers

I've resolved this one. What you need to do is FULLY SEPARATE ANY GTK CALL FROM ANY THREAD.

Those error occured because there were still some code accessing gtk ui from worker thread (thread that doing my calculation in the background). What I need to do is just separate ALL gtk call from thread by using gobject.idle_add(some_fuction_telling_gtk_what_to_do)

This is a sample:

def stop_progress(self):
    self.worker.join()
    self.label.set_text('idle') 

def working_thread(self, num):
    self.textview.set_text(num)
    Process.heavyworks2(num)    
    gobject.idle_add(self.stop_progress)

self.worker = threading.Thread(target=self.working_thread, args=[100000])
self.worker.start()

You see from that code a function that suppose to working in the background (working_thread(self,num)) still having a line accessing gtk call (self.textview.set_text(num)). Separate that code into a function and call it from your thread using gobject.idle_add(gtk_call_function).

It's become like this.

def stop_progress(self):
    self.worker.join()
    self.label.set_text('idle') 

def updateTextView(self, num):
    self.textview.set_text(num)     

def working_thread(self, num):
    gobject.idle_add(self.updateTextView, num)
    Process.heavyworks2(num)    
    gobject.idle_add(self.stop_progress)

self.worker = threading.Thread(target=self.working_thread, args=[100000])
self.worker.start()

So, one important point here is don't update gtk ui directly from any thread. Just separate every code accessing gtk into a function and call it by gobject.idle_add() from thread.

like image 52
user2435611 Avatar answered Mar 26 '23 06:03

user2435611


Perhaps you have to do this first:

import gobject
gobject.threads_init()

Does that keep it from crashing? (Check out http://faq.pygtk.org/index.py?req=show&file=faq20.006.htp)

like image 39
Velimir Mlaker Avatar answered Mar 26 '23 04:03

Velimir Mlaker