Access violation exception occurred by cairo_win32_surface_get_dc api
I have a legacy application that uses the Cairo library to draw images and texts. Sometimes this application crashes. I don't know the reproduction path, it's pretty rare and random. I have created crash dumps and found that every time I got an access violation from cairo_win32_surface_get_dc
function.
Here is the source code from Cairo -
HDC cairo_win32_surface_get_dc (cairo_surface_t *surface)
{
if (surface->backend->type == CAIRO_SURFACE_TYPE_WIN32)
return to_win32_surface(surface)->dc;
if (_cairo_surface_is_paginated (surface)) {
cairo_surface_t *target = _cairo_paginated_surface_get_target (surface);
if (target->backend->type == CAIRO_SURFACE_TYPE_WIN32_PRINTING)
return to_win32_surface(target)->dc;
}
return NULL;
}
This function returns the HDC associated with this surface, or NULL if none. It also returns NULL if the surface is not a win32 surface.
From the crash dump I've found, surface->backend
was NULL when this crash occurred. Which is expected if you look at the code above, it doesn't check if surface
or surface->backend
is NULL or not.
My application's code looks like below -
if( mySurface ) {
hDC = cairo_win32_surface_get_dc(mySurface);
}
My idea was to add an extra check if mySurface->backend
is NULL or not before calling cairo_win32_surface_get_dc
but, mySurface->backend
is not accessible from here. Gives me the following error -
Error C2027 use of undefined type '_cairo_surface'
Error (active) E0393 pointer to incomplete class type is not allowed
Also note that this block doesn't crash always, so I'm unable to figure out what's going wrong here.
After googling a bit, I found some people are checking for any previous error like this-
if (cairo_surface_status(mySurface) == 0) {
hDC = cairo_win32_surface_get_dc(mySurface);
}
Will this change fix my issue? Any ideas?