Hi all,

I have posted a message regarding "segv in expose event" early this year,
http://mail.gnome.org/archives/gtk-devel-list/2007-March/msg00086.html

some people suggested we upgrade to the latest gtk library to see whether
the problem still remained or not. I found that this issue still existed.
Further investigation has been performed and something interesting showed
up. I found that in function _gdk_window_process_expose, the serial variable
in GdkWindowQueueItem structure just overflowed, so that it became less than
xevent.serial, so the item would be removed from the queue, which SHOULD NOT
happen.

Here is the proof:
(gdb) bt
#0  0xb794ba9a in g_object_remove_weak_pointer (object=0x9a35d88,
weak_pointer_location=0x9a35a88)
   at gobject.c:1548
#1  0xb7a2bd61 in queue_item_free (item=0x9a35a88) at gdkgeometry-x11.c:914
#2  0xb7a2c0a5 in _gdk_window_process_expose (window=0x9a38f18, serial=3992,
area=0xffffffff)
   at gdkgeometry-x11.c :1051
#3  0xb7a25b9d in gdk_event_translate (display=0x829a4d0, event=0x99e03c0,
xevent=0xbf81eaf0,
   return_exposes=0) at gdkevents-x11.c:1484
#4  0xb7a266fd in _gdk_events_queue (display=0x829a4d0) at gdkevents-x11.c:2067
#5  0xb7a26891 in gdk_event_dispatch (source=0xffffffff, callback=0,
user_data=0x0) at gdkevents-x11.c:2127
#6  0xb78dae4a in g_main_dispatch (context=0x82a51f8) at gmain.c:1895
#7  0xb78dbf28 in g_main_context_dispatch (context=0x82a51f8) at gmain.c
:2441
#8  0xb78dc260 in g_main_context_iterate (context=0x82a51f8, block=1,
dispatch=1, self=0x82d7be8)
   at gmain.c:2522
#9  0xb78dc8a3 in g_main_loop_run (loop=0x99e1660) at gmain.c:2726
#10 0xb7b62403 in gtk_main () at gtkmain.c:1172
#11 0x0809c07b in main (argc=1, argv=0xbf81ede4) at main.cc:260
(gdb) f 2
#2  0xb7a2c0a5 in _gdk_window_process_expose (window=0x9a38f18, serial=3992,
area=0xffffffff)
   at gdkgeometry-x11.c:1051
1051                  queue_item_free (item);
(gdb) l
1046                }
1047              else
1048                {
1049                  queue_delete_link (display_x11->translate_queue,
1050
display_x11->translate_queue->head);
1051                  queue_item_free (item);
1052                }
1053            }
1054        }
1055
(gdb) p *(GdkWindowQueueItem *)tmp_list->data
$31 = {window = 0x9bbcc28, serial = 341, type = GDK_WINDOW_QUEUE_ANTIEXPOSE,
u = {translate = {
     dx = 163135504, dy = 46399540}, antiexpose = {area = 0x9b94010}}}
(gdb) p *(GdkWindowQueueItem *)tmp_list->prev->data <= overflow
$32 = {window = 0x9a35d88, serial = 57, type = GDK_WINDOW_QUEUE_ANTIEXPOSE,
u = {translate = {
     dx = 161749920, dy = 16}, antiexpose = {area = 0x9a41ba0}}}
(gdb) p *(GdkWindowQueueItem *)tmp_list->prev->prev->data      <=here,
serial value is near the max ulong
$33 = {window = 0x9a36010, serial = 4294967176, type =
GDK_WINDOW_QUEUE_ANTIEXPOSE, u = {translate = {
     dx = 161771960, dy = 52}, antiexpose = {area = 0x9a471b8}}}
(gdb) p *(GdkWindowQueueItem *)tmp_list->prev->prev->prev->data
$34 = {window = 0x9a36010, serial = 4294966893, type =
GDK_WINDOW_QUEUE_ANTIEXPOSE, u = {translate = {
     dx = 161807208, dy = 16}, antiexpose = {area = 0x9a4fb68}}}

I know that serial will not overflow in the normal case, but when we need to
build up some long standing application which keeps create windows, serial
overflow seems unvoidable in the long run. So is there any way to reset
serial to avoid the situation or this is really a bug in the gdk library
itself. Any suggestion/comment is welcome. I attach the code of
_gdk_window_process_expose for your reference purpose.

1017    void
1018    _gdk_window_process_expose (GdkWindow    *window,
1019                                gulong        serial,
1020                                GdkRectangle *area)
1021    {
1022      GdkWindowImplX11 *impl;
1023      GdkRegion *invalidate_region = gdk_region_rectangle (area);
1024      GdkRegion *clip_region;
1025      GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY
(window));
(gdb)
1026      impl = GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl);
1027
1028      if (display_x11->translate_queue)
1029        {
1030          GList *tmp_list = display_x11->translate_queue->head;
1031
1032          while (tmp_list)
1033            {
1034              GdkWindowQueueItem *item = tmp_list->data;
1035              tmp_list = tmp_list->next;
(gdb)
1036
1037              if (serial < item->serial)
1038                {
1039                  if (item->window == window)
1040                    {
1041                      if (item->type == GDK_WINDOW_QUEUE_TRANSLATE)
1042                        gdk_region_offset (invalidate_region, item->
u.translate.dx, item->u.translate.dy);
1043                      else          /* anti-expose */
1044                        gdk_region_subtract (invalidate_region, item->
u.antiexpose.area);
1045                    }
1046                }
1047              else
1048                {
1049                  queue_delete_link (display_x11->translate_queue,
1050
display_x11->translate_queue->head);
1051                  queue_item_free (item);
1052                }
1053            }
1054        }
_______________________________________________
gtk-devel-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtk-devel-list

Reply via email to