Opened 13 years ago

Closed 13 years ago

#3799 closed defect (fixed)

cairo/pdf driver crashes when rending raster in pdf

Reported by: bfraser Owned by: tbonfort
Priority: normal Milestone: 6.0 release
Component: Output-PDF Version: 6.0
Severity: normal Keywords: cairo pdf tif
Cc: dmorissette, tamas, tbonfort

Description

shp2img crashes when rendering a tif into a PDF using Cairo

MAP
  NAME 'topo'
  # Map image size
  SIZE  800 800
  UNITS meters
  EXTENT 285000 5435000 291000 5440000
  PROJECTION
    'proj=utm'
    'zone=12'
    'ellps=WGS84'
    'datum=WGS84'
    'units=m'
    'no_defs'
  END

  # Background color for the map canvas -- change as desired
  IMAGECOLOR 255 255 255

  IMAGETYPE CAIRO_PDF
  
  OUTPUTFORMAT
   NAME 'CAIRO_PDF'
   DRIVER CAIRO/PDF
   EXTENSION "pdf"
  END

  LAYER
    NAME '082h04'
    TYPE RASTER
    DATA 'C:\Inetpub\wwwroot\Topo\data\raster\SHADING\08H04.tif'
    STATUS DEFAULT
    OPACITY 50
    PROJECTION
    'proj=longlat'
    'ellps=GRS80'
    'datum=NAD83'
    'no_defs'
    END

  END
  
END

Change History (13)

comment:1 by dmorissette, 13 years ago

Cc: dmorissette added
Milestone: 6.0 release

We'll need more info and/or a more complete testcase to reproduce. You seem to be on Windows, are you using MS4W or did you build the binary yourself? Maybe a dev on Windows could test this?

I have tested rendering a TIF to PDF with shp2img on Linux with 6.0-trunk and don't get any error. Valgrind does not report any memory problem either. Here is the mapfile that I used in case you want to test it. It uses the file grey.tif from msautotest/gdal/data:

MAP

NAME TEST
STATUS ON
SIZE 400 300
EXTENT 0.5 0.5 399.5 299.5
IMAGECOLOR 255 255 255
SHAPEPATH "../gdal"
IMAGETYPE CAIRO_PDF

OUTPUTFORMAT
   NAME 'CAIRO_PDF'
   DRIVER CAIRO/PDF
   EXTENSION "pdf"
END

LAYER
  NAME grey
  TYPE raster
  STATUS default
  OPACITY 50
  DATA data/grey.tif
END

END # of map file

comment:2 by bfraser, 13 years ago

I'm using Windows XP Service Pack 3. I've tried MS4W and built it in debug using Tamas' SDK for VS 2010. Basically it crashes (even with test .map given above) in mapcairo.c, line 600, in saveImageCairo():

cairo_surface_finish (r->surface);

The line before this is:

cairo_renderer *r = CAIRO_RENDERER(img);

and the img object looks reasonable going in, but I'll have to do some digging to validate the r object coming out...

Thanks! Brent

comment:3 by dmorissette, 13 years ago

Cc: tamas tbonfort added

Adding Tamas to CC in case he has an idea. (tbonfort also in CC, but he's offline for the next 2 weeks)

comment:4 by tamas, 13 years ago

I'm experiencing the same problem even with data/grey.tif. The crash is happening inside the cairo libraries somewhere.

in reply to:  2 comment:6 by tbonfort, 13 years ago

Replying to bfraser:

I'm using Windows XP Service Pack 3. I've tried MS4W and built it in debug using Tamas' SDK for VS 2010. Basically it crashes (even with test .map given above) in mapcairo.c, line 600, in saveImageCairo():

cairo_surface_finish (r->surface);

The line before this is:

cairo_renderer *r = CAIRO_RENDERER(img);

and the img object looks reasonable going in, but I'll have to do some digging to validate the r object coming out...

Thanks! Brent

Brent,

what happens if you change the call cairo_surface_finish to cairo_surface_flush ?

comment:7 by bfraser, 13 years ago

It no longer crashes at cairo_surface_flush, but it does crash in freeImageCairo at cairo_destroy(r->cr); Commenting that line out allows shp2img to exit without crashing, but the resulting pdf is zero bytes.

comment:8 by tbonfort, 13 years ago

I can reproduce this on Linux to.

  • the bug only appears with with cairo versions 1.10.x . versions 1.8.x seem ok.
  • The problem is that the pdf writer expects the incorporated image data to still be accessible at the moment we finish the surface. The mapserver workflow is to create the raster image, tell the renderer to incorporate it, then delete it.

a workaround that allows the creation of an image and prevents the segfault is

Index: mapdraw.c
===================================================================
--- mapdraw.c	(revision 11547)
+++ mapdraw.c	(working copy)
@@ -1241,7 +1241,7 @@
         	renderer->mergeRasterBuffer( image, &rb, 1.0, 0, 0, 0, 0, rb.width, rb.height );
         }
 
-        msFreeRasterBuffer(&rb);
+        //msFreeRasterBuffer(&rb);
         
         
     }

This is not a viable solution as it will leak large quantities of memory (well, it is viable under plain cgi, but we don't want to rely on that).

Until cairo is updated or we find a workaround with them, the solution is either to avoid raster layers in pdf output, or use cairo version 1.8.10

in reply to:  8 comment:9 by tamas, 13 years ago

Replying to tbonfort:

Until cairo is updated or we find a workaround with them, the solution is either to avoid raster layers in pdf output, or use cairo version 1.8.10

Good job. Did anyone report this back to cairo (with high priority) so as to to get it fixed in one of the subsequent releases?

comment:10 by tbonfort, 13 years ago

Tamas, on my macbook with macports that uses a snapshot version of cairo (1.11.2), I don't have this problem. I'm guessing the cairo team has already corrected this, although I don't know when they plan on releasing 1.12

comment:11 by tbonfort, 13 years ago

Ok, so this isn't as simple as it seems, the bug is also present in 1.11.2, it's just that darwin seems nicer than linux/windows in allowing access to memory that has already been freed. To summarize:

  • with 1.8.10: results ok, although the pdf contains artifacts on some vector symbols and paths
  • with cairo>=1.10.0:
    • without the freeRasterBuffer patch:
      • unix/windows: crash
      • darwin: no crash, but corrupt output
    • with the freeRasterBufferPatch:
      • unix/darwin: correct output, but memory leak
      • windows: ?? output, memory leak

comment:12 by tbonfort, 13 years ago

Owner: changed from assefa to tbonfort
Status: newassigned

I've found the bug and am further testing it before committing. We were not telling cairo to drop references to the raster data, so it was holding onto it until the pdf surface was finished.

comment:13 by tbonfort, 13 years ago

Resolution: fixed
Status: assignedclosed

fixed in r11549

Note: See TracTickets for help on using tickets.