ports/181095: net-p2p/transmission-gtk fails to start

Romain Tartière romain at FreeBSD.org
Mon Aug 19 10:12:41 UTC 2013


Hi!

I can reproduce this: any GTK3 application crash when attempting to
display a tray icon (I use stalonetray, can't tell if another
notification icon bar will also fail).  If I stop stalonetray, audacious
and transmission will start. If the application is configured to not
display a status icon, no crash occurs when a status area is available.

GTK2 applications are unaffected.

gdb session of a transmission-gtk crash (ports updated a couple days ago):
------------------------------------------------------------------------
GNU gdb (GDB) 7.6 [GDB v7.6 for FreeBSD]
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-portbld-freebsd9.1".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/local/bin/transmission-gtk...done.
(gdb) r
Starting program: /usr/local/bin/transmission-gtk 
[New LWP 101300]
[New Thread 80b807400 (LWP 101300)]
[New Thread 80baa8800 (LWP 101407)]
[New Thread 80bbd2000 (LWP 101408)]
[New Thread 80bb41400 (LWP 101409)]
[New Thread 80e497400 (LWP 101410)]
[New Thread 80de33c00 (LWP 101411)]
Assertion failed: (! _cairo_surface_has_mime_data (surface)), function cairo_surface_mark_dirty_rectangle, file cairo-surface.c, line 1174.

Program received signal SIGABRT, Aborted.
[Switching to Thread 80b807400 (LWP 101300)]
0x000000080777f23c in thr_kill () from /lib/libc.so.7
(gdb) bt
#0  0x000000080777f23c in thr_kill () from /lib/libc.so.7
#1  0x000000080782363b in abort () from /lib/libc.so.7
#2  0x0000000807806d35 in __assert () from /lib/libc.so.7
#3  0x000000080233f6ab in *INT_cairo_surface_mark_dirty_rectangle (surface=0x80bab7300, x=0, y=0, width=24, height=24) at cairo-surface.c:1174
#4  0x0000000800d3051b in gtk_tray_icon_draw (widget=0x80d7c8000, cr=0x8025dc400 <_context_stash>) at gtktrayicon-x11.c:378
#5  0x0000000800b365a2 in _gtk_marshal_BOOLEAN__BOXEDv (closure=0x80b925060, return_value=0x7fffffffc5e0, instance=0x80d7c8000, args=0x7fffffffc780, 
    marshal_data=0x800d303e0 <gtk_tray_icon_draw>, n_params=1, param_types=0x80b819190) at gtkmarshalers.c:130
#6  0x0000000800cd050a in gtk_widget_draw_marshallerv (closure=0x80b925060, return_value=0x7fffffffc5e0, instance=0x80d7c8000, args=0x7fffffffc780, 
    marshal_data=0x800d303e0 <gtk_tray_icon_draw>, n_params=1, param_types=0x80b819190) at gtkwidget.c:906
#7  0x0000000804cf8486 in g_type_class_meta_marshalv (closure=0x80b925060, return_value=0x7fffffffc5e0, instance=0x80d7c8000, args=0x7fffffffc780, marshal_data=0x120, 
    n_params=1, param_types=0x80b819190) at gclosure.c:997
#8  0x0000000804cf7fb2 in _g_closure_invoke_va (closure=0x80b925060, return_value=0x7fffffffc5e0, instance=0x80d7c8000, args=0x7fffffffc780, n_params=1, param_types=0x80b819190)
    at gclosure.c:840
#9  0x0000000804d14b09 in g_signal_emit_valist (instance=0x80d7c8000, signal_id=20, detail=0, var_args=0x7fffffffc780) at gsignal.c:3234
#10 0x0000000804d15f89 in g_signal_emit (instance=0x80d7c8000, signal_id=20, detail=0) at gsignal.c:3384
#11 0x0000000800cd9e51 in _gtk_widget_draw_internal (widget=0x80d7c8000, cr=0x8025dc400 <_context_stash>, clip_to_size=1) at gtkwidget.c:6165
#12 0x0000000800cdaaaa in gtk_widget_send_expose (widget=0x80d7c8000, event=0x7fffffffca10) at gtkwidget.c:6545
#13 0x0000000800b34b15 in gtk_main_do_event (event=0x7fffffffca10) at gtkmain.c:1631
#14 0x0000000801134d3c in _gdk_event_emit (event=0x7fffffffca10) at gdkevents.c:69
#15 0x0000000801147f79 in _gdk_window_process_updates_recurse (window=0x80d443d10, expose_region=0x80d6154a0) at gdkwindow.c:4006
#16 0x000000080118ab2d in gdk_x11_window_process_updates_recurse (window=0x80d443d10, region=0x80d6154a0) at gdkwindow-x11.c:5203
#17 0x0000000801148324 in gdk_window_process_updates_internal (window=0x80d443d10) at gdkwindow.c:4194
#18 0x0000000801148722 in gdk_window_process_updates_with_mode (window=0x80d443d10, recurse_mode=2) at gdkwindow.c:4374
#19 0x0000000801153c43 in gdk_window_paint_on_clock (clock=0x80d43ebc0, data=0x80d443d10) at gdkwindow.c:11626
#20 0x0000000804cfaf66 in g_cclosure_marshal_VOID__VOIDv (closure=0x80d5cfcb0, return_value=0x0, instance=0x80d43ebc0, args=0x7fffffffd120, marshal_data=0x0, n_params=0, 
    param_types=0x0) at gmarshal.c:115
#21 0x0000000804cf7fb2 in _g_closure_invoke_va (closure=0x80d5cfcb0, return_value=0x0, instance=0x80d43ebc0, args=0x7fffffffd120, n_params=0, param_types=0x0) at gclosure.c:840
#22 0x0000000804d14b09 in g_signal_emit_valist (instance=0x80d43ebc0, signal_id=140, detail=0, var_args=0x7fffffffd120) at gsignal.c:3234
#23 0x0000000804d16137 in g_signal_emit_by_name (instance=0x80d43ebc0, detailed_signal=0x801191efa "paint") at gsignal.c:3424
#24 0x000000080113c533 in gdk_frame_clock_paint_idle (data=0x80d43ebc0) at gdkframeclockidle.c:419
#25 0x0000000801129662 in gdk_threads_dispatch (data=0x80bb9f6a0) at gdk.c:788
#26 0x00000008055a9973 in g_timeout_dispatch (source=0x80d77e8d0, callback=0x801129620 <gdk_threads_dispatch>, user_data=0x80bb9f6a0) at gmain.c:4413
#27 0x00000008055a7c6a in g_main_dispatch (context=0x80b92eb40) at gmain.c:3054
#28 0x00000008055a895d in g_main_context_dispatch (context=0x80b92eb40) at gmain.c:3630
#29 0x00000008055a8b1d in g_main_context_iterate (context=0x80b92eb40, block=1, dispatch=1, self=0x80bb51200) at gmain.c:3701
#30 0x00000008055a8be1 in g_main_context_iteration (context=0x80b92eb40, may_block=1) at gmain.c:3762
#31 0x0000000804a098ee in g_application_run (application=0x80b8ae170, argc=1, argv=0x7fffffffd750) at gapplication.c:1623
#32 0x00000000004358da in main (argc=1, argv=0x7fffffffd750) at main.c:659
(gdb) f 3
#3  0x000000080233f6ab in *INT_cairo_surface_mark_dirty_rectangle (surface=0x80bab7300, x=0, y=0, width=24, height=24) at cairo-surface.c:1174
1174	    assert (! _cairo_surface_has_mime_data (surface));
(gdb) l
1169	
1170	    /* The application *should* have called cairo_surface_flush() before
1171	     * modifying the surface independently of cairo (and thus having to
1172	     * call mark_dirty()). */
1173	    assert (! _cairo_surface_has_snapshots (surface));
1174	    assert (! _cairo_surface_has_mime_data (surface));
1175	
1176	    surface->is_clear = FALSE;
1177	
1178	    if (surface->backend->mark_dirty_rectangle != NULL) {
(gdb) f 4
#4  0x0000000800d3051b in gtk_tray_icon_draw (widget=0x80d7c8000, cr=0x8025dc400 <_context_stash>) at gtktrayicon-x11.c:378
378	          cairo_surface_mark_dirty_rectangle (target, 
(gdb) l
373	          XClearArea (GDK_WINDOW_XDISPLAY (window),
374	                      GDK_WINDOW_XID (window),
375	                      clip.x, clip.y,
376	                      clip.width, clip.height,
377	                      False);
378	          cairo_surface_mark_dirty_rectangle (target, 
379	                                              clip.x, clip.y,
380	                                              clip.width, clip.height);
381	        }
382	    }
(gdb) 
------------------------------------------------------------------------

Porking with surface->mime_data if frame #3 before the assertions allows
transmission to start:

------------------------------------------------------------------------
Breakpoint 1, *INT_cairo_surface_mark_dirty_rectangle (surface=0x80bab7300, x=0, y=0, width=24, height=24) at cairo-surface.c:1174
1174	    assert (! _cairo_surface_has_mime_data (surface));
(gdb) l
1169	
1170	    /* The application *should* have called cairo_surface_flush() before
1171	     * modifying the surface independently of cairo (and thus having to
1172	     * call mark_dirty()). */
1173	    assert (! _cairo_surface_has_snapshots (surface));
1174	    assert (! _cairo_surface_has_mime_data (surface));
1175	
1176	    surface->is_clear = FALSE;
1177	
1178	    if (surface->backend->mark_dirty_rectangle != NULL) {
(gdb) p surface
$1 = (cairo_surface_t *) 0x80bab7300
(gdb) p *surface
$2 = {backend = 0x8025daae0 <cairo_xlib_surface_backend>, device = 0x80d63e5c0, type = CAIRO_SURFACE_TYPE_XLIB, content = CAIRO_CONTENT_COLOR, ref_count = {ref_count = 4}, 
  status = CAIRO_STATUS_SUCCESS, unique_id = 34, finished = 0, is_clear = 0, has_font_options = 0, owns_device = 1, user_data = {size = 2, num_elements = 2, element_size = 24, 
    elements = 0x80d7d04b8, is_snapshot = 0}, mime_data = {size = 1, num_elements = 1, element_size = 24, elements = 0x80d7d04e8, is_snapshot = 0}, device_transform = {xx = 1, 
    yx = 0, xy = 0, yy = 1, x0 = 0, y0 = 0}, device_transform_inverse = {xx = 1, yx = 0, xy = 0, yy = 1, x0 = 0, y0 = 0}, device_transform_observers = {
    next = 0x8025dc6a0 <_context_stash+672>, prev = 0x8025dc508 <_context_stash+264>}, x_resolution = 72, y_resolution = 72, x_fallback_resolution = 300, 
  y_fallback_resolution = 300, snapshot_of = 0x0, snapshot_detach = 0x0, snapshots = {next = 0x80bab7408, prev = 0x80bab7408}, snapshot = {next = 0x0, prev = 0x0}, 
  font_options = {antialias = CAIRO_ANTIALIAS_DEFAULT, subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT, lcd_filter = CAIRO_LCD_FILTER_DEFAULT, 
    hint_style = CAIRO_HINT_STYLE_DEFAULT, hint_metrics = CAIRO_HINT_METRICS_DEFAULT}}
(gdb) p surface->mime_data
$3 = {size = 1, num_elements = 1, element_size = 24, elements = 0x80d7d04e8, is_snapshot = 0}
(gdb) set surface->mime_data.size = 0
(gdb) set surface->mime_data.num_elements = 0
(gdb) set surface->mime_data.element_size = 0
(gdb) set surface->mime_data.elements = 0
(gdb) set surface->mime_data.is_snapshot = 0
(gdb) c
Continuing.
[New Thread 813c54c00 (LWP 101546)]
[New Thread 813c55000 (LWP 101547)]
[New Thread 813c55400 (LWP 101548)]
[New Thread 813c55800 (LWP 101549)]
[New Thread 813c55c00 (LWP 101550)]
[New Thread 813c56000 (LWP 101551)]
[New Thread 813c56400 (LWP 101552)]
[New Thread 813c56800 (LWP 101553)]
[New Thread 813c56c00 (LWP 101554)]
[New Thread 813c57000 (LWP 101555)]
[...]
------------------------------------------------------------------------

It looks like the surface has some unattended mime_data attached to it
that cause the assertion failure. Since cairo was not updated recently,
it might be a change introduced in the update of gtk30 to 3.8.

I failed at finding some decent cairo API function to fix this properly
in x11-toolkits/gtk30, but an ugly patch into cairo do the trick and
allows audacious and transmission-gtk to display status icons:

------------------------------------------------------------------------
--- src/cairo-surface.c.orig
+++ src/cairo-surface.c
@@ -1171,6 +1171,10 @@
      * modifying the surface independently of cairo (and thus having to
      * call mark_dirty()). */
     assert (! _cairo_surface_has_snapshots (surface));
+
+    if (_cairo_surface_has_mime_data (surface))
+      _cairo_surface_detach_mime_data (surface);
+
     assert (! _cairo_surface_has_mime_data (surface));
 
     surface->is_clear = FALSE;
------------------------------------------------------------------------

Maybe gnome@ (in Cc:) has more insights into this issue related to cairo
and gtk3 and help in fixing this issue.

Regards,
Romain

-- 
Romain Tartière <romain at FreeBSD.org>  http://people.FreeBSD.org/~romain/
pgp: 8234 9A78 E7C0 B807 0B59  80FF BA4D 1D95 5112 336F (ID: 0x5112336F)
(plain text =non-HTML= PGP/GPG encrypted/signed e-mail much appreciated)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 663 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-gnome/attachments/20130819/f4f7ff9d/attachment.sig>


More information about the freebsd-gnome mailing list