[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:
Chris Wilson 2009-05-15 17:40:26 +01:00
parent 791a6fa399
commit 31596cf2b2
7 changed files with 85 additions and 9 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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 :

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}
/**

View file

@ -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