Re: cairo release 1.12.4 now available

Klaus Stengel <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
Hi Uli,

Uli Schlachter wrote:
> What makes you think that cairo unconditionally requires the latest version of
> the Xrender extension? And why do you quote the code that actually checks the
> version number (XRenderQueryVersion()) as a proof for this? Doesn't this really
> mean that cairo actually does the right thing and checks the XRender version
> being used?
> 
> Please, when reporting bugs, try to explain what exactly you are doing and what
> goes wrong. If you want to get fancy and really proof that cairo tries to use
> something which is not in a given version of Xrender, it would be nice if you
> could write a short, self-contained C program which does the wrong thing.

please find a simple test program and a corresponding backtrace of the X
error in the attachments. I tested with the library versions currently
available on Debian testing (libcairo 0.12.2). The XRENDER version
reported by the X11 server is 0.10:

$ xdpyinfo -ext RENDER | grep RENDER
    RENDER
RENDER version 0.10 opcode: 149, base error: 167

Nevertheless, libcairo tries to perform an XRenderComposite operation
with PictOpDifference, which is a feature only available on XRender 0.11
when running the attached test program:

| (gdb) break XRenderComposite
| Function "XRenderComposite" not defined.
| Make breakpoint pending on future shared library load? (y or [n]) y
| 
| Breakpoint 1 (XRenderComposite) pending.
| (gdb) run
| Starting program: /tmp/cairocrash 
| [Thread debugging using libthread_db enabled]
| Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
| 
| Breakpoint 1, XRenderComposite (dpy=0x6425d0, op=op@entry=57,
| src=37748749, mask=37748752, dst=37748748, src_x=src_x@entry=15,
| src_y=src_y@entry=126, mask_x=mask_x@entry=0, mask_y=mask_y@entry=0,
| dst_x=dst_x@entry=15, dst_y=dst_y@entry=126, width=width@entry=114,
| height=height@entry=3)

As it can be seen above, the op parameter has the decimal value 57,
which corresponds to 0x39 hex. According to X11/extensions/render.h,
0x39 is PictOpDifference and listed in a section titled "Operators only
available in version 0.11".

The above call results in the following X error:
The error was 'BadValue (integer parameter out of range for operation)'.
  (Details: serial 237 error_code 2 request_code 149 minor_code 8)
  (Note to programmers: normally, X errors are reported asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the GDK_SYNCHRONIZE environment
   variable to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error()
   function.)

The main problem seems to be the function _render_operator() in
cairo-xlib-render.c, which just translates any cairo operator to the
corresponding XRender code without any checks. This function is used in
various calls to XRender functions.

These 0.11-only operators are actually used by applications, so this is
not only a theoretical problem. My preferred E-Mail client "evolution"
is currently unusable because it immediately crashes when trying to
answer any E-Mail. The reason is that the GtkHTML widget used in the
editor window depends on the difference operator to draw its text
cursor.

Regards,
Klaus

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
backtrace.txt (text/plain, 5.5 KB)
#0  gdk_x_error (xdisplay=0x6425d0, error=0x7fffffffc520)
    at /tmp/buildd/gtk+3.0-3.4.2/./gdk/x11/gdkmain-x11.c:268
#1  0x00007ffff4443563 in _XError (dpy=0x6425d0, rep=<optimized out>)
    at ../../src/XlibInt.c:1583
#2  0x00007ffff44405d1 in handle_error (dpy=0x6425d0, err=0x768f50, 
    in_XReply=<optimized out>) at ../../src/xcb_io.c:212
#3  0x00007ffff4440615 in handle_response (dpy=0x6425d0, response=0x768f50, 
    in_XReply=<optimized out>) at ../../src/xcb_io.c:324
#4  0x00007ffff4441420 in _XReply (dpy=0x6425d0, rep=0x7fffffffc6c0, extra=0, 
    discard=1) at ../../src/xcb_io.c:626
#5  0x00007ffff443cdfd in XSync (dpy=0x6425d0, discard=0)
    at ../../src/Sync.c:44
#6  0x00007ffff443ce8b in _XSyncFunction (dpy=<optimized out>)
    at ../../src/Synchro.c:35
#7  0x00007ffff7b6eaf9 in composite (abstract_dst=0x768550, op=57, 
    abstract_src=0x768fa0, abstract_mask=0x769130, src_x=15, src_y=126, 
    mask_x=0, mask_y=0, dst_x=15, dst_y=126, width=114, height=3)
    at /tmp/buildd/cairo-1.12.2/src/cairo-xlib-render-compositor.c:539
#8  0x00007ffff7b1c452 in composite_mask (
    compositor=compositor@entry=0x7ffff7ddc1c0, dst=dst@entry=0x768550, 
    closure=closure@entry=0x7fffffffc8d0, 
    op=op@entry=CAIRO_OPERATOR_DIFFERENCE, 
    src_pattern=src_pattern@entry=0x7fffffffc950, 
    src_sample=src_sample@entry=0x7fffffffc930, dst_x=dst_x@entry=0, 
    dst_y=dst_y@entry=0, extents=extents@entry=0x7fffffffc90c, clip=0x768e90)
    at /tmp/buildd/cairo-1.12.2/src/cairo-mask-compositor.c:1179
#9  0x00007ffff7b1e29c in clip_and_composite (compositor=0x7ffff7ddc1c0, 
    draw_func=0x7ffff7b1c350 <composite_mask>, 
    mask_func=0x7ffff7b1cc70 <composite_mask_clip_boxes>, 
    draw_closure=0x7fffffffc8d0, extents=0x7fffffffc8d0, need_clip=1)
    at /tmp/buildd/cairo-1.12.2/src/cairo-mask-compositor.c:766
#10 0x00007ffff7b090b1 in _cairo_compositor_mask (compositor=0x7ffff7ddc1c0, 
    surface=0x768550, op=<optimized out>, source=<optimized out>, 
    mask=<optimized out>, clip=<optimized out>)
    at /tmp/buildd/cairo-1.12.2/src/cairo-compositor.c:106
#11 0x00007ffff7b484f0 in _cairo_surface_mask (surface=0x768550, 
    op=CAIRO_OPERATOR_DIFFERENCE, source=0x7fffffffcf60, mask=0x7fffffffcc30, 
    clip=0x768a20) at /tmp/buildd/cairo-1.12.2/src/cairo-surface.c:1921
#12 0x00007ffff7b1da6b in _cairo_mask_compositor_stroke (
    _compositor=<optimized out>, extents=0x7fffffffcee0, path=0x698e98, 
    style=0x7fffffffd860, ctm=0x7fffffffd2f0, ctm_inverse=0x7fffffffd320, 
    tolerance=0.10000000000000001, antialias=CAIRO_ANTIALIAS_DEFAULT)
    at /tmp/buildd/cairo-1.12.2/src/cairo-mask-compositor.c:1292
#13 0x00007ffff7b0918e in _cairo_compositor_stroke (compositor=0x7ffff7ddc1c0, 
    surface=0x768550, op=<optimized out>, source=<optimized out>, 
    path=0x698e98, style=0x7fffffffd860, ctm=0x7fffffffd2f0, 
    ctm_inverse=ctm_inverse@entry=0x7fffffffd320, 
    tolerance=0.10000000000000001, 
    antialias=antialias@entry=CAIRO_ANTIALIAS_DEFAULT, 
    clip=clip@entry=0x7689d0)
    at /tmp/buildd/cairo-1.12.2/src/cairo-compositor.c:153
#14 0x00007ffff7b72d93 in _cairo_xlib_surface_stroke (
    _surface=<optimized out>, op=<optimized out>, source=<optimized out>, 
    path=<optimized out>, style=<optimized out>, ctm=<optimized out>, 
    ctm_inverse=0x7fffffffd320, tolerance=<optimized out>, 
    antialias=CAIRO_ANTIALIAS_DEFAULT, clip=0x7689d0)
    at /tmp/buildd/cairo-1.12.2/src/cairo-xlib-surface.c:1367
#15 0x00007ffff7b4861e in _cairo_surface_stroke (surface=0x768550, 
    op=CAIRO_OPERATOR_DIFFERENCE, source=0x7fffffffd890, path=0x698e98, 
    stroke_style=0x7fffffffd860, ctm=0x7fffffffd2f0, 
    ctm_inverse=0x7fffffffd320, tolerance=0.10000000000000001, 
    antialias=CAIRO_ANTIALIAS_DEFAULT, clip=0x7689d0)
    at /tmp/buildd/cairo-1.12.2/src/cairo-surface.c:2043
#16 0x00007ffff7b4d4a5 in _cairo_surface_offset_stroke (surface=0x768550, x=0, 
    y=0, op=op@entry=CAIRO_OPERATOR_DIFFERENCE, 
    source=source@entry=0x7fffffffd890, path=path@entry=0x698e98, 
    stroke_style=stroke_style@entry=0x7fffffffd860, ctm=0x698de8, 
    ctm_inverse=ctm_inverse@entry=0x698e18, tolerance=<optimized out>, 
    antialias=antialias@entry=CAIRO_ANTIALIAS_DEFAULT, 
    clip=clip@entry=0x7689d0)
    at /tmp/buildd/cairo-1.12.2/src/cairo-surface-offset.c:183
#17 0x00007ffff7b4e616 in _cairo_surface_subsurface_stroke (
    abstract_surface=0x768240, op=CAIRO_OPERATOR_DIFFERENCE, 
    source=0x7fffffffd890, path=0x698e98, stroke_style=0x7fffffffd860, 
    ctm=<optimized out>, ctm_inverse=0x698e18, tolerance=<optimized out>, 
    antialias=CAIRO_ANTIALIAS_DEFAULT, clip=0x765790)
    at /tmp/buildd/cairo-1.12.2/src/cairo-surface-subsurface.c:199
#18 0x00007ffff7b4861e in _cairo_surface_stroke (surface=0x768240, 
    op=CAIRO_OPERATOR_DIFFERENCE, source=0x7fffffffd890, path=0x698e98, 
    stroke_style=0x7fffffffd860, ctm=0x698de8, ctm_inverse=0x698e18, 
    tolerance=0.10000000000000001, antialias=CAIRO_ANTIALIAS_DEFAULT, 
    clip=0x765790) at /tmp/buildd/cairo-1.12.2/src/cairo-surface.c:2043
#19 0x00007ffff7b108b5 in _cairo_gstate_stroke (gstate=0x698cf8, 
    path=path@entry=0x698e98)
    at /tmp/buildd/cairo-1.12.2/src/cairo-gstate.c:1171
#20 0x00007ffff7b0ac54 in _cairo_default_context_stroke (abstract_cr=0x698b30)
    at /tmp/buildd/cairo-1.12.2/src/cairo-default-context.c:965
#21 0x00007ffff7b040d5 in INT_cairo_stroke (cr=0x698b30)
    at /tmp/buildd/cairo-1.12.2/src/cairo.c:2146
#22 0x0000000000400e72 in draw (w=0x763820, cr=0x698b30, unused=0x0)
    at cairocrash.c:16
cairocrash.c (text/x-csrc, 1 KB)
#include <cairo.h>
#include <gtk/gtk.h>

/* Compile on Linux with:
c99 -D_XOPEN_SOURCE=600 -O0 -g3 cairocrash.c -o cairocrash \
  `pkg-config --cflags --libs cairo` `pkg-config --cflags --libs gtk+-3.0`
*/

static void
draw(GtkWidget *w, cairo_t *cr, gpointer unused) {
	cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE);
	cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);

	cairo_move_to(cr, 16.5,  127.5);
	cairo_line_to(cr, 127.5, 127.5);
	cairo_stroke(cr);
}

int
main(int argc, char *argv[])
{
	gtk_init(&argc, &argv);

	GtkWidget *mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_default_size(GTK_WINDOW(mainwin), 256, 256);
	gtk_window_set_title(GTK_WINDOW(mainwin), "Cairo test");
	g_signal_connect(G_OBJECT(mainwin), "destroy", G_CALLBACK(gtk_main_quit), NULL);

	GtkWidget *da = gtk_drawing_area_new();
	g_signal_connect(G_OBJECT(da), "draw", G_CALLBACK(draw), NULL);
	gtk_container_add(GTK_CONTAINER(mainwin), da);
	
	gtk_widget_show(da);
	gtk_widget_show_all(mainwin);

	gtk_main();
	return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.