Bug 23067

Summary: using clear drawing operator crashes printing
Product: cairo Reporter: Julian Lamb <thepurlieu>
Component: image backendAssignee: Carl Worth <cworth>
Status: RESOLVED FIXED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: medium    
Version: 1.8.6   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: Test file to reproduce bug

Description Julian Lamb 2009-07-31 21:11:29 UTC
I'm a developer for gerbv, which uses cairo for rendering/printing/etc.  A bug was posted recently in which gerbv crased during printing.  The output is:

gerbv: /build/buildd/cairo-1.8.6/src/cairo-surface.c:817: _cairo_surface_set_device_scale: Assertion `status == CAIRO_STATUS_SUCCESS' failed.

The relevent stack trace is:

#0  0x00007f973da36fb5 in raise () from /lib/libc.so.6
#1  0x00007f973da38bc3 in abort () from /lib/libc.so.6
#2  0x00007f973da2ff09 in __assert_fail () from /lib/libc.so.6
#3  0x00007f973dda55a5 in ?? () from /usr/lib/libcairo.so.2
#4  0x00007f973dd95713 in ?? () from /usr/lib/libcairo.so.2
#5  0x00007f973dd95a2a in ?? () from /usr/lib/libcairo.so.2
#6  0x00007f973dd95b3d in ?? () from /usr/lib/libcairo.so.2
#7  0x00007f973dda3bda in cairo_surface_show_page () from /usr/lib/libcairo.so.2
#8  0x00007f973dd8ccb0 in ?? () from /usr/lib/libcairo.so.2
#9  0x00007f973dd87249 in cairo_show_page () from /usr/lib/libcairo.so.2
#10 0x00007f97401a3e2d in gtk_print_operation_draw_page_finish () from /usr/lib/libgtk-x11-2.0.so.0
#11 0x00007f97401a44a9 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#12 0x00007f973fdb704b in ?? () from /usr/lib/libgdk-x11-2.0.so.0
#13 0x00007f973e03320a in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#14 0x00007f973e0368e0 in ?? () from /usr/lib/libglib-2.0.so.0
#15 0x00007f973e036dad in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#16 0x00007f97401a43d5 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#17 0x00007f97401a4fab in gtk_print_operation_run () from /usr/lib/libgtk-x11-2.0.so.0
#18 0x000000000041e4e0 in callbacks_print_activate (menuitem=<value optimized out>, 
    user_data=<value optimized out>) at callbacks.c:504

I traced the problem back to the portion of the file in which we call:

cairo_set_operator (CAIRO_OPERATOR_CLEAR);

to render a portion of the file, effectively clearing a portion of the rendered context. The on-screen rendering works completely fine with this command, however when we render the file to a cairo_t and then pass it to the gtk_print API, it crashes every time.  Has this crash ever been seen before?

Cheers,
Julian
Comment 1 Chris Wilson 2009-08-05 00:52:20 UTC
I don't recognise this, and to hit any assertion inside Cairo means something strange and completely unexpected has happened.

I didn't reproduce this printing one of examples packaged with gerbv -- but that could just be user error.

What would be great would be to confirm this bug with HEAD and then to grab a cairo-trace of the application hitting the bug. But, to be honest, I have a strong suspicion that I may have fixed this by reworking the clipping since 1.8.
Comment 2 Julian Lamb 2009-08-05 06:38:24 UTC
Created attachment 28365 [details]
Test file to reproduce bug
Comment 3 Julian Lamb 2009-08-05 06:39:25 UTC
Thanks for looking into this Chris.  If you have gerbv running, could you try
the attached file and see if you can get the problem?  Just load it and click
print, then select an actual printer (not file).

If not, it may well be fixed in HEAD.  I can definitely compile HEAD and see if
it is still there...just let me know.

Cheers--
Julian
Comment 4 Chris Wilson 2009-08-05 06:59:46 UTC
(In reply to comment #3)
> Thanks for looking into this Chris.  If you have gerbv running, could you try
> the attached file and see if you can get the problem?  Just load it and click
> print, then select an actual printer (not file).

That's the killer - using an actual printer. Thanks I can reproduce this locally in both 1.8 and master.
Comment 5 Chris Wilson 2009-08-05 07:20:05 UTC
So the issue is that when printing the fallback resolution of the printer is set to 0 dpi. CAIRO_OPERATOR_CLEAR can not be handled natively by PDF/PS (except where the CLEAR affects the whole surface and we just discard all previous content) which triggers a fallback. As we attempt to create an fallback image with 0 pixels, we are understandably confused.

The backtrace pin-points the caller to _gtk_printer_create_cairo_surface(), gtk/gtkprinter.c:924 so I'll go and look for the culprit there. But first I'll commit the guards to cairo. (Pushed to 1.8, in my local queue for master)

In any event, my advice would be to rethink the use of CLEAR as you want to avoid unnecessary image fallbacks. And you need to check for errors after drawing and before commiting the print job -- though perhaps this error will need to be caught inside GTK+.

Marking as fixed... I'll go raise a bug+patch for GTK+.
Comment 6 Julian Lamb 2009-08-05 08:05:48 UTC
Thanks Chris.  As far as avoiding CLEAR operations, I'm not sure we have much choice.  The RS274X file format has a "negative polarity" command, which pretty much lets the user "erase" previously drawn objects by drawing a negative object over them.  Since we allow transparency, I didn't see any other way than to use the CLEAR operator to draw over it, since we can't just draw the object using the background color.  Are there some other methods to achieve the same effect?

Cheers--
Julian
Comment 7 Chris Wilson 2009-08-05 08:07:22 UTC
FYI, the GTK+ bug is http://bugzilla.gnome.org/show_bug.cgi?id=590861
Comment 8 Chris Wilson 2009-08-05 08:12:22 UTC
(In reply to comment #6)
> Thanks Chris.  As far as avoiding CLEAR operations, I'm not sure we have much
> choice.  The RS274X file format has a "negative polarity" command, which pretty
> much lets the user "erase" previously drawn objects by drawing a negative
> object over them.  Since we allow transparency, I didn't see any other way than
> to use the CLEAR operator to draw over it, since we can't just draw the object
> using the background color.  Are there some other methods to achieve the same
> effect?

I don't think so, other than a wishlist idea for flattening to objects rather than images. Though I'd ask the question on the cairo mailing list, as with a wider audience someone may have a good solution...

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.