mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 13:28:03 +02:00
[debug] Check image contents using memcheck.
As an aide to tracking down the source of uninitialised reads, run VALGRIND_CHECK_MEM_IS_DEFINED() over the contents of image surfaces at the boundary between backends, e.g. upon setting a glyph image or acquiring a source image.
This commit is contained in:
parent
791a6fa399
commit
31596cf2b2
7 changed files with 85 additions and 9 deletions
|
|
@ -77,3 +77,45 @@ cairo_debug_reset_static_data (void)
|
|||
|
||||
CAIRO_MUTEX_FINALIZE ();
|
||||
}
|
||||
|
||||
#if HAVE_VALGRIND
|
||||
#include <memcheck.h>
|
||||
|
||||
void
|
||||
_cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
|
||||
{
|
||||
const cairo_image_surface_t *image = (cairo_image_surface_t *) surface;
|
||||
const uint8_t *bits;
|
||||
int row, width;
|
||||
|
||||
if (surface == NULL)
|
||||
return;
|
||||
|
||||
if (! RUNNING_ON_VALGRIND)
|
||||
return;
|
||||
|
||||
bits = image->data;
|
||||
switch (image->format) {
|
||||
case CAIRO_FORMAT_A1:
|
||||
width = (image->width + 7)/8;
|
||||
break;
|
||||
case CAIRO_FORMAT_A8:
|
||||
width = image->width;
|
||||
break;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
width = image->width*4;
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
return;
|
||||
}
|
||||
|
||||
for (row = 0; row < image->height; row++) {
|
||||
VALGRIND_CHECK_MEM_IS_DEFINED (bits, width);
|
||||
/* and then silence any future valgrind warnings */
|
||||
VALGRIND_MAKE_MEM_DEFINED (bits, width);
|
||||
bits += image->stride;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -996,6 +996,8 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
|||
|
||||
_cairo_image_surface_assume_ownership_of_data ((*surface));
|
||||
|
||||
_cairo_debug_check_image_surface_is_defined (&(*surface)->base);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1452,6 +1452,8 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
|
|||
|
||||
pixman_image_unref (pixman_image);
|
||||
|
||||
_cairo_debug_check_image_surface_is_defined (&image->base);
|
||||
|
||||
status = _cairo_surface_clone_similar (dst, &image->base,
|
||||
opaque ?
|
||||
CAIRO_CONTENT_COLOR :
|
||||
|
|
|
|||
|
|
@ -654,6 +654,8 @@ read_png (struct png_read_closure_t *png_closure)
|
|||
_cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
|
||||
data = NULL;
|
||||
|
||||
_cairo_debug_check_image_surface_is_defined (surface);
|
||||
|
||||
status = _cairo_memory_stream_destroy (png_closure->png_data,
|
||||
&mime_data,
|
||||
&mime_data_length);
|
||||
|
|
|
|||
|
|
@ -2409,6 +2409,9 @@ _cairo_scaled_glyph_set_surface (cairo_scaled_glyph_t *scaled_glyph,
|
|||
{
|
||||
if (scaled_glyph->surface != NULL)
|
||||
cairo_surface_destroy (&scaled_glyph->surface->base);
|
||||
|
||||
/* sanity check the backend glyph contents */
|
||||
_cairo_debug_check_image_surface_is_defined (&surface->base);
|
||||
scaled_glyph->surface = surface;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1153,6 +1153,8 @@ _cairo_surface_acquire_source_image (cairo_surface_t *surface,
|
|||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
|
|
@ -1161,9 +1163,14 @@ _cairo_surface_acquire_source_image (cairo_surface_t *surface,
|
|||
if (surface->backend->acquire_source_image == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return _cairo_surface_set_error (surface,
|
||||
surface->backend->acquire_source_image (surface,
|
||||
image_out, image_extra));
|
||||
status = surface->backend->acquire_source_image (surface,
|
||||
image_out, image_extra);
|
||||
if (unlikely (status))
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
_cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1222,6 +1229,8 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
|||
cairo_rectangle_int_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
|
|
@ -1230,12 +1239,17 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
|||
if (surface->backend->acquire_dest_image == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return _cairo_surface_set_error (surface,
|
||||
surface->backend->acquire_dest_image (surface,
|
||||
interest_rect,
|
||||
image_out,
|
||||
image_rect,
|
||||
image_extra));
|
||||
status = surface->backend->acquire_dest_image (surface,
|
||||
interest_rect,
|
||||
image_out,
|
||||
image_rect,
|
||||
image_extra);
|
||||
if (unlikely (status))
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
_cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2741,4 +2741,15 @@ CAIRO_END_DECLS
|
|||
#include "cairo-malloc-private.h"
|
||||
#include "cairo-hash-private.h"
|
||||
|
||||
#if HAVE_VALGRIND
|
||||
|
||||
cairo_private void
|
||||
_cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface);
|
||||
|
||||
#else
|
||||
|
||||
#define _cairo_debug_check_image_surface_is_defined(X)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue