<html>
    <head>
      <base href="https://bugs.freedesktop.org/">
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Assertion "(_cairo_atomic_int_get (&(&surface->ref_count)->ref_count) > 0)""
   href="https://bugs.freedesktop.org/show_bug.cgi?id=91967#c28">Comment # 28</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Assertion "(_cairo_atomic_int_get (&(&surface->ref_count)->ref_count) > 0)""
   href="https://bugs.freedesktop.org/show_bug.cgi?id=91967">bug 91967</a>
              from <span class="vcard"><a class="email" href="mailto:jskarvad@redhat.com" title="Jaroslav Škarvada <jskarvad@redhat.com>"> <span class="fn">Jaroslav Škarvada</span></a>
</span></b>
        <pre>Created <span class=""><a href="attachment.cgi?id=124212" name="attach_124212" title="Proposed fix">attachment 124212</a> <a href="attachment.cgi?id=124212&action=edit" title="Proposed fix">[details]</a></span> <a href='page.cgi?id=splinter.html&bug=91967&attachment=124212'>[review]</a>
Proposed fix

Drawable may be destroyed/invalidated asynchronously before control flow
reaches _get_image_surface function or at any time the code from
_get_image_surface is executed - this may lead to undesired effects like double
free (which is prevented by assert), X server errors, crashes. The failing path
is e.g. the following:

- XShmGetImage @797 fails because the drawable doesn't exist
- cairo_surface_destroy @809 destroys the image (now there is no image)
- it tries XGetImage @818, but fails so it sets surface->use_pixmap =
CAIRO_ASSUME_PIXMAP (it wrongly suppose the surface is a window)
- now it tries to create pixmap @827, but it fails because the drawable doesn't
exist
- the check @879 passes and sets the error to CAIRO_STATUS_NO_MEMORY (which is
probably not the correct error, but that's not the main problem)
- the control flow is redirected to the BAIL @881
- the BAIL code started @1007
- it checks ximage and destroys it if it exists @1008
- the status is CAIRO_STATUS_NO_MEMORY so the check @1013 passed
- boom! the image is destroyed second time @1014

I think the main problem is that the two BAIL jumps (@848 and @881) doesn't
count with the fact that there is no image at the moment. The rest of the BAIL
jumps are OK, because there is already some image created.

The attached patch is my attempt to fix the problem. Not the most elegant
approach, but it seems to work for me. It also adds X error NOOP handler to X
calls which may fail due to the non-existent drawable/pixmap not to SIGTRAP the
code. With the patch applied the attached reproducer doesn't fail.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are the QA Contact for the bug.</li>
      </ul>
    </body>
</html>