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