[cairo] Cairo crash with a simple stroke (win32)

Fred Beca fredbca21 at gmail.com
Mon Sep 9 08:17:49 PDT 2013


Hi there,

I am bumping this old thread, since the issue is still there in 1.12.16,
and I have not figured out yet how to properly fix it. The issue is clearly
linked to the win32 surface's image size that does not cover the entire
surface (because of clipping regions), but I would need some more insight
about how it is supposed to work to fix it.

Has anyone an idea?

Regards,

Fred.


On Wed, Nov 7, 2012 at 1:56 PM, Fred bca21 <fredbca21 at gmail.com> wrote:

> Hi Again,
>
> It appears that the bug seems to happen because the extents of the
> fallback image has an offset in its origin.
> when performing the mapping of the surface to an image, in
> cairo-win32-display-surface.c, on line 467:
> return _cairo_image_surface_map_to_image (surface->image, extents);
>
> this actually creates a pixman image with an invalid pointer, that is
> supposed to be compensated by the device transform, as you can see in
> cairo-image-surface.c on line 805:
>     uint8_t *data;
>
>     data = other->data;
>     data += extents->y * other->stride; // THIS POINTER IS OUTSIDE OF
> THE ACTUAL IMAGE (the image is created with the actual extent, not the
> entire surface extent)
>     data += extents->x * PIXMAN_FORMAT_BPP (other->pixman_format)/ 8;
>
> surface =_cairo_image_surface_create_with_pixman_format (data,
>
> other->pixman_format,
>                                                         extents->width,
>                                                         extents->height,
>                                                         other->stride);
>
>     cairo_surface_set_device_offset (surface, -extents->x,
> -extents->y); /// THIS IS SUPPOSED TO COMPENSATE THE OFFSET ABOVE
>     return surface;
>
> But in the end, when reaching the _fill_xrgb32_lerp_opaque_spans
> function, the data pointer is still the wrong one (as offset in the
> function above, not compensated by the device transform).
>
> So either the device transform should be applied at some point and it
> is not, or the mapping of the image is wrong and should not use the
> origin of the extents,
>
> That's all I can do for now with my imited knowledge, but I hope it
> helps a little bit and maybe this will motivate someone to check this
> out.
>
> Regards,
>
> Fred.
>
> 2012/11/7 Fred bca21 <fredbca21 at gmail.com>:
> > Hi,
> >
> > No surprise: the issue is still here in 1.12.8. Running the code below
> > crashes in _fill_xrgb32_lerp_opaque_spans.
> >
> > If anyone can give me an idea of how to get started on debugging this,
> > I'd be glad to help fixing this problem. I have already spent some
> > time on it, but it's pretty hard to understand where the composite
> > destination data pointer is changed without not much knowledge of the
> > cairo code.
> >
> > Just wondering: why isn't there much interest for this problem?
> >
> > Thanks!
> >
> > Fred.
> >
> > {
> >                 // build a bitmap (same issue with DIB, whatever the bit
> depth)
> >                 HDC dc=::CreateCompatibleDC(NULL);
> >                 HBITMAP hBmp=::CreateCompatibleBitmap(dc,100,200);
> >                 ::SelectObject(dc,hBmp);
> >
> >                 // set clip region for the DC to one single line in the
> middle of the bitmap
> >                 HRGN hrgn = CreateRectRgn(0,100,100, 101);
> >                 SelectClipRgn(dc, hrgn);
> >                 ::DeleteObject(hrgn);
> >
> >                 // create cairo context
> >                 cairo_surface_t* surface=cairo_win32_surface_create(dc);
> >                 if(surface)
> >                 {
> >                         cairo_t* context=cairo_create(surface);
> >                         if(context)
> >                         {
> >                                 // draw one line
> >                                 cairo_move_to(context,1, 1);
> >                                 cairo_line_to(context,10,120);
> >                                 cairo_set_source_rgb(context,1,1,1);
> >
> >                                 // CRASHES HERE:
> >                                 cairo_stroke(context);
> >
> >                                 // cleanup
> >                                 cairo_destroy(context);
> >                         }
> >                         cairo_surface_destroy(surface);
> >                 }
> >         }
> >
> > 2012/11/5 Fred bca21 <fredbca21 at gmail.com>:
> >> Hi,
> >>
> >> Thank you Martin for your answer. The thing is, it is a feature that a
> >> surface built on a HDC gets the right clipping region. It is indeed
> >> possible to manually overwrite, re-compute and apply the clipping
> >> region to the cairo context, but it is probably better just to fix
> >> cairo and this feature :-). Also, this problem is also probably
> >> occuring in other cases (it is a crash in the compositing functions).
> >>
> >> Has anyone found a way to fix it properly?
> >>
> >> I'll double check with the new 1.12.8 that has just been released
> >> (there seem to be changes in this area), but it would be great to have
> >> feedback from the experts.
> >>
> >> Regards,
> >>
> >> Fred.
> >>
> >>
> >> 2012/10/30 Martin Schlemmer <Martin.Schlemmer at nwu.ac.za>:
> >>> Hi,
> >>>
> >>>> After some additionnal debugging, it appears that the raw data pointer
> >>>> (unsigned char *data;) in the destination image surface for the
> >>>> compositor is invalid, hence the crash. I have not been able to find
> >>>> out where this comes from yet (the multiple casts throughout the code
> >>>> does not make easy for a newcomer to track this field in the image
> >>>> surface). All I can say is it is valid when the fallback image for the
> >>>> surface is created, at the beginning of the cairo_stroke call.
> >>>
> >>>> Does anybody have any clue? I feel a bit lonely on this issue :).
> >>>
> >>> I am not sure if its a feature or a bug, but if you remove the bits
> that sets the Clip Region directly on the HDC, it does not crash.
> >>> I assume that you should rather use:
> >>>
> >>>   cairo_rectangle ()
> >>>   cairo_clip ()
> >>>
> >>> on the created context.
> >>>
> >>> I could however be incorrect, and that creating a surface from a HDC
> which already has a Clip Region set directly on the HDC should not give
> current results - maybe somebody can verify?
> >>>
> >>>
> >>> Regards,
> >>> Martin
> >>>
> >>>
> >>>>2012/10/25 Fred bca21 <fredbca21 at gmail.com>:
> >>>> Hi,
> >>>>
> >>>> I have just tested with the latest cairo release (1.12.6), and it
> >>>> appears that the issue is still here (crash at the exact same
> >>>> location). Has anyone an idea of how to fix it? Should I maybe post
> >>>> this to the bugs mailing list?
> >>>>
> >>>> Regards,
> >>>>
> >>>> Fred.
> >>>>
> >>>>
> >>>> 2012/10/19 Fred bca21 <fredbca21 at gmail.com>:
> >>>>> Hi,
> >>>>>
> >>>>> I am new to this list but I have been using cairo and monitoring
> posts
> >>>>> for a couple of months now. I have a strange issue on windows when
> the
> >>>>> intersection between the clipping region and the drawing is very
> >>>>> small, so I am posting here with the hope that someone can help (I am
> >>>>> a bit too new to cairo's internals to debug this problem).
> >>>>>
> >>>>> Typically, the simple code below crashes (I am using a DDB bitmap for
> >>>>> the example, but it also crashes with any DC).
> >>>>>
> >>>>> #include "cairo.h"
> >>>>> #include "cairo-win32.h"
> >>>>> #include <windows.h>
> >>>>> {
> >>>>> // build a bitmap (same issue with DIB, whatever the bit depth)
> >>>>> HDC dc=::CreateCompatibleDC(NULL);
> >>>>> HBITMAP hBmp=::CreateCompatibleBitmap(dc,100,200);
> >>>>> ::SelectObject(dc,hBmp);
> >>>>>
> >>>>> // set clip region for the DC to one single line in the middle of
> the bitmap
> >>>>> HRGN hrgn = CreateRectRgn(0,100,100, 101);
> >>>>> SelectClipRgn(dc, hrgn);
> >>>>> ::DeleteObject(hrgn);
> >>>>>
> >>>>> // create cairo context
> >>>>> cairo_surface_t* surface=cairo_win32_surface_create(dc);
> >>>>> if(surface)
> >>>>> {
> >>>>> cairo_t* context=cairo_create(surface);
> >>>>> if(context)
> >>>>> {
> >>>>> // draw one line
> >>>>> cairo_move_to(context,1, 1);
> >>>>> cairo_line_to(context,10,120);
> >>>>> cairo_set_source_rgb(context,1,1,1);
> >>>>>
> >>>>> // CRASHES HERE (see below):
> >>>>> cairo_stroke(context);
> >>>>>
> >>>>> // cleanup
> >>>>> cairo_destroy(context);
> >>>>> }
> >>>>> cairo_surface_destroy(surface);
> >>>>> }
> >>>>> }
> >>>>>
> >>>>> The crash occurs in cairo-image-compositor.c, on line 2197, in
> >>>>> _fill_xrgb32_lerp_opaque_spans():
> >>>>>
> >>>>>                 } else while (len--) {
> >>>>>                     // On this line below, d has an invalid address
> >>>>>                     *d = lerp8x4 (r->u.fill.pixel, a, *d);
> >>>>>                     d++;
> >>>>>                 }
> >>>>>
> >>>>> If it may help, am using the static lib version of the latest release
> >>>>> (1.12.4 - pixman 26.2), and it crashes in debug or release mode, 32
> or
> >>>>> 64-bit windows. It's too bad because this crash occurs all the time
> in
> >>>>> my code that extensively uses clipping regions!
> >>>>>
> >>>>> This crash also occurs with the previous version of cairo (1.12.2)
> and
> >>>>> pixman 26.0, but at a different stage (in pixman if I remember well),
> >>>
> >>>
> >>> Vrywaringsklousule / Disclaimer:
> http://www.nwu.ac.za/it/gov-man/disclaimer.html
> >>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20130909/4f50d610/attachment.html>


More information about the cairo mailing list