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

Re: [libvirt] [libvirt-glib 5/5] mainloop: don't reschedule deleted timeouts/watches



On Mon, Jun 25, 2012 at 11:03:16AM +0100, Daniel P. Berrange wrote:
> On Wed, Jun 20, 2012 at 12:29:51PM +0200, Christophe Fergeau wrote:
> > The deletion of libvirt timeouts/watches is done in 2 steps:
> > - the first step is synchronous and unregisters the timeout/watch
> >   from glib mainloop
> > - the second step is asynchronous and triggered from the first step.
> >   It releases the memory used for bookkeeping for the timeout/watch
> >   being deleted
> > 
> > This is done this way to avoid some possible deadlocks when
> > reentering the sync callback while freeing the memory associated
> > with the timeout/watch.
> > 
> > However, it's possible to call gvir_event_update_handle after
> > gvir_event_remove_handle but before _event_handle_remove does
> > the final cleanup. When this happen, _update_handle will reregister
> > the handle with glib mainloop, and bad things will happen when
> > a glib callback is triggered for this event after _event_handle_remove
> > has freed the memory associated with this handle watch.
> 
> That's clearly possible, but it is also illegal use of the events
> API by some client code, since the timer/watch id is not valid
> after calling remove(). Do you actually see this occurring in
> real life ?

Yes, I've seen this with gnome-boxes when starting a VM and then letting it
run in the background, see the cover letter for a few more details

I've just added

if (h->removed)
    G_BREAKPOINT;

to gvir_event_timeout_find to catch a backtrace when this happens:

(gdb) bt
#0  gvir_event_handle_find (watch=1) at libvirt-glib-event.c:202
#1  0x00007ffff6670b78 in gvir_event_handle_update (watch=1, events=1)
    at libvirt-glib-event.c:218
#2  0x00007ffff5f400e9 in virEventUpdateHandle (watch=1, events=1)
    at util/event.c:70
#3  0x00007ffff60823f1 in virNetSocketUpdateIOCallback
(sock=0x7fffdc001fe0,
    events=1) at rpc/virnetsocket.c:1384
#4  0x00007ffff606e74e in virNetClientIOUpdateCallback
(client=0x7fffdc001e20,
    enableCallback=true) at rpc/virnetclient.c:1454
#5  0x00007ffff606ecec in virNetClientIncomingEvent (sock=0x7fffdc001fe0,
    events=2, opaque=0x7fffdc001e20) at rpc/virnetclient.c:1659
#6  0x00007ffff608213c in virNetSocketEventHandle (watch=1, fd=26,
events=2,
    opaque=0x7fffdc001fe0) at rpc/virnetsocket.c:1314
#7  0x00007ffff66708cd in gvir_event_handle_dispatch
(source=0x7fffdc001f60,
    condition=G_IO_OUT, opaque=0x7fffdc001930) at libvirt-glib-event.c:136
#8  0x00007ffff1e20cb4 in g_io_unix_dispatch (source=0x7fffdc0017d0,
    callback=0x7ffff66707f8 <gvir_event_handle_dispatch>,
    user_data=0x7fffdc001930) at giounix.c:166
#9  0x00007ffff1dd1f15 in g_main_dispatch (context=0x6fea30) at
gmain.c:2539
#10 0x00007ffff1dd2bda in g_main_context_dispatch (context=0x6fea30)
    at gmain.c:3075
#11 0x00007ffff1dd2dbd in g_main_context_iterate (context=0x6fea30,
block=1,
    dispatch=1, self=0x728780) at gmain.c:3146
#12 0x00007ffff1dd2e81 in g_main_context_iteration (context=0x6fea30,
    may_block=1) at gmain.c:3207
#13 0x00007ffff25dbe7c in g_application_run (application=0x709890, argc=0,
    argv=0x0) at gapplication.c:1607
#14 0x000000000041dec8 in boxes_app_run (self=0x1525010) at app.c:1187
#15 0x00000000004506f4 in _vala_main (args=0x7fffffffd738, args_length1=1)
    at main.c:729
#16 0x000000000045075e in main (argc=1, argv=0x7fffffffd738) at main.c:740

It happens at more or less random times, so I'm not sure if I'll be able to
catch a backtrace when the watch is removed.

Christophe

Attachment: pgpJ1RRQ5iAYp.pgp
Description: PGP signature


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