Re: Event loop hangup when using TimeoutSource and IdleSource



Robert,

I just did an initial step through of the code attaching to the program via gdb -p <pid> after it hung and the bt shows that it is getting stuck after doing one of the set_text calls for a label. So it seems to possibly be a race condition still. The library that I wrote that talks to the device runs in its own thread separate from the gtkmm app thread. It talks to the device via file descriptors to the serial port and uses select() to get the data back. It then reassembles the data according to the protocol embedded datatype and passes it as a void * to the callback wrapper function like the one I posted. I've already proven this library out with a ncurses GUI that I wrote since it was pretty quick and easy and I'd done several ncurses GUIs in the past. Not to say that there aren't bugs still, but the general flow of the library is pretty sound.

The only functions that ever change properties of the GUI widgets are always called via a callback from the IdleSource instance. Since the event loop should be idle, I don't understand why things would randomly hang up.

I have interspersed some entering and leaving debug statements in the functions and that's how I know that it randomly hangs at certain points.

One run ended on the getPrimaryPackCurrentCb function. The following is the backtrace from gdb:

INFO: (14:58:50) Entering setControlSetpointCb

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb6cc5720 (LWP 20547)]
0xb762f742 in sigc::internal::trackable_callback_list::remove_callback () from /usr/lib/libsigc-2.0.so.0
(gdb) bt
#0 0xb762f742 in sigc::internal::trackable_callback_list::remove_callback () from /usr/ lib/libsigc-2.0.so.0 #1 0xb762fadc in sigc::trackable::remove_destroy_notify_callback () from /usr/lib/libsigc-2.0.so.0 #2 0x0805c2f8 in sigc::internal::slot_do_unbind::operator() (this=0xbfb633a4, t=0x993a378)
    at /usr/include/sigc++-2.0/sigc++/functors/slot_base.h:166
#3 0x0805c312 in sigc::internal::with_type_pointer<true, sigc::trackable, sigc::internal::limit_derived_target<sigc::trackable*, sigc::internal::slot_do_unbind> >::execute_ (_A_type= 0x993a378, _A_action= 0xbfb633a4) at /usr/include/sigc++-2.0/sigc++/visit_each.h:88 #4 0x0805c32c in sigc::internal::limit_derived_target<sigc::trackable*, sigc::internal::slot_do_unbind>::operator()<sigc::trackable> (this=0xbfb633a4, _A_type= 0x993a378) at /usr/include/sigc++-2.0/ sigc++/visit_each.h:100 #5 0x0805c346 in sigc ::visit_each<sigc::internal::limit_derived_target<sigc::trackable*, sigc::internal::slot_do_unbind>, sigc::trackable> (_A_action= 0xbfb633a4, _A_functor= 0x993a378) at /usr/include/sigc+ +-2.0/sigc++/visit_each.h:144 #6 0x0805c368 in sigc ::visit_each<sigc::internal::limit_derived_target<sigc::trackable*, sigc::internal::slot_do_unbind>, emsac::Emsac, true> (_A_action= 0xbfb633a4, _A_target= 0x9945064) at /usr/include/sigc+ +-2.0/sigc++/limit_reference.h:121 #7 0x0805c385 in sigc ::visit_each<sigc::internal::limit_derived_target<sigc::trackable*, sigc::internal::slot_do_unbind>, bool, emsac::Emsac> (_A_action= 0xbfb633a4, _A_target= 0x994505c) at /usr/include/sigc+ +-2.0/sigc++/functors/mem_fun.h:1806 #8 0x0805c3a2 in sigc ::visit_each<sigc::internal::limit_derived_target<sigc::trackable*, sigc::internal::slot_do_unbind>, sigc::bound_mem_functor0<bool, emsac::Emsac> > (_A_action= 0xbfb633a4, _A_target= 0x9945058)
    at /usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:267
#9 0x0805c3ce in sigc::visit_each_type<sigc::trackable*, sigc::internal::slot_do_unbind, sigc::adaptor_functor<sigc::bound_mem_functor0<bool, emsac::Emsac> > > (_A_action= 0xbfb633cc, _A_functor= 0x9945058) at /usr/include/sigc+ +-2.0/sigc++/visit_each.h:170 #10 0x0805c418 in sigc::internal::typed_slot_rep<sigc::bound_mem_functor0<bool, emsac::Emsac> >::destroy (data=0x9945040)
    at /usr/include/sigc++-2.0/sigc++/functors/slot.h:60
#11 0xb763021f in sigc::slot_base::~slot_base () from /usr/lib/ libsigc-2.0.so.0
#12 0xb7667bcd in destroy_notify_callback (data=0x987af48) at main.cc:36
#13 0xb72931e4 in g_source_callback_unref (cb_data=0x9936950) at / build/buildd/glib2.0-2.20.1/glib/gmain.c:931 #14 0xb72937ce in g_source_destroy_internal (source=0x9882fc8, context=0x97eb0f8, have_lock=1)
    at /build/buildd/glib2.0-2.20.1/glib/gmain.c:710
#15 0xb7293be0 in IA__g_main_context_dispatch (context=0x97eb0f8) at / build/buildd/glib2.0-2.20.1/glib/gmain.c:1839 #16 0xb72970eb in g_main_context_iterate (context=0x97eb0f8, block=1, dispatch=1, self=0x97f7648)
    at /build/buildd/glib2.0-2.20.1/glib/gmain.c:2448
#17 0xb72975ba in IA__g_main_loop_run (loop=0x9931900) at /build/ buildd/glib2.0-2.20.1/glib/gmain.c:2656 #18 0xb78047d9 in IA__gtk_main () at /build/buildd/gtk+2.0-2.16.1/gtk/ gtkmain.c:1205
#19 0xb7d483d7 in Gtk::Main::run_impl (this=0xbfb63678) at main.cc:536
#20 0xb7d484fe in Gtk::Main::run (window= 0x987eb88) at main.cc:490
---Type <return> to continue, or q <return> to quit---
#21 0x0804d104 in main (argc=Cannot access memory at address 0x29
) at src/main.cpp:96


Thanks for your help so far,

Jim


On Sep 24, 2009, at 2:37 PM, Robert Pearce wrote:

Hi Jim,

On Thu, 24 Sep 2009 13:31:53 -0400 you wrote:

I am trying to create a pretty simple gtkmm application. The purpose
of the application is to display the status of an attached device and
to also send commands to the device to control it. The device is
connected to the computer via a serial port and abstracted by a
library API that I also wrote. My gtkmm application is designed to
poll the device for various status via one function that gets called
every 100 ms via a TimeoutSource.

That's not very different from an application I'm developing.

<snip>

The weird part is that this "loop" of calling the updateEMSStatus()
function via the TimeoutSource hangs randomly. It sometimes will hang
after one cycle through (meaning through every status get request that fires in 1 second, 2 seconds, 5 seconds, etc)), and sometimes it'll do
several cycles through with the timer returning hundreds of times.

I seem to recall having similar problems early on, but I can't remember the details.

It
doesn't seem to get stuck in any of my functions, it seems to be the
Glib event loop that is getting stuck because my GUI becomes
completely unresponsive. Any thoughts?

Well one thought is that that is an unsafe deduction. The glib event loop is single-threaded and needs everything it calls to return in a timely manner. If one of your functions hangs, whether a command sender or a callback, the result will be to lock up the glib event loop.

Am I not using the Idlesource
in a proper manner?

Possibly, but your code snippet didn't look wrong.

Is this a resource leak somehow?

Unlikely - it's too quick

How would I go
about debugging where in the Glib event loop it might be hanging at?

With a debugger? Or possibly by scattering a few "entering this", "leaving that" debug messages around.

How are you handling the returned serial data? Are you polling? Calling select? Using read? Using a separate thread? Relying on glib via a Glib::IOChannel (which is the method I use)?


Rob
_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
http://mail.gnome.org/mailman/listinfo/gtkmm-list



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]