[MAPSERVER-USERS] Antwort: Re: leaking memory in java mapscript (was Re: thread safety)

rich.fromm nospam420 at yahoo.com
Thu Feb 21 14:58:56 PST 2008



rich.fromm wrote:
> 
> I have finally been able to successfully run a single iteration in
> valgrind
> and have it report a leak in the code:
> 
> --- begin ---
> ==21154== 41,600 bytes in 65 blocks are possibly lost in loss record 46 of
> 55
> ==21154==    at 0x401C6CA: calloc (vg_replace_malloc.c:279)
> ==21154==    by 0x42B15E3: gdCalloc (gdhelpers.c:79)
> ==21154==    by 0x42A4F49: gdImageCreate (gd.c:104)
> ==21154==    by 0x40BFEA9: msImageCreateWithPaletteGD (mapgd.c:3460)
> ==21154==    by 0x40C04E8: msSaveImageBufferGD (mapgd.c:3695)
> ==21154==    by 0x40CCD6B: msSaveImageBufferAGG (mapagg.cpp:2248)
> ==21154==    by 0x40A70F8: msSaveImageBuffer (maputil.c:682)
> ==21154==    by 0x406CB6C:
> Java_edu_umn_gis_mapscript_mapscriptJNI_imageObj_1getBytes
> (mapscript_wrap.c:2586)
> ==21154==    by 0x88614AA: ???
> ==21154==    by 0x885BA63: ???
> ==21154==    by 0x885BA63: ???
> ==21154==    by 0x8859218: ???
> ==21154== 
> ==21154== 
> ==21154== 271,588 (7,268 direct, 264,320 indirect) bytes in 1 blocks are
> definitely lost in loss record 49 of 55
> ==21154==    at 0x401D38B: malloc (vg_replace_malloc.c:149)
> ==21154==    by 0x42B15AC: gdMalloc (gdhelpers.c:85)
> ==21154==    by 0x42A4EA4: gdImageCreate (gd.c:83)
> ==21154==    by 0x40BFEA9: msImageCreateWithPaletteGD (mapgd.c:3460)
> ==21154==    by 0x40C04E8: msSaveImageBufferGD (mapgd.c:3695)
> ==21154==    by 0x40CCD6B: msSaveImageBufferAGG (mapagg.cpp:2248)
> ==21154==    by 0x40A70F8: msSaveImageBuffer (maputil.c:682)
> ==21154==    by 0x406CB6C:
> Java_edu_umn_gis_mapscript_mapscriptJNI_imageObj_1getBytes
> (mapscript_wrap.c:2586)
> ==21154==    by 0x88614AA: ???
> ==21154==    by 0x885BA63: ???
> ==21154==    by 0x885BA63: ???
> ==21154==    by 0x8859218: ???
> --- end ---
> 

Here's my hunch from a somewhat cursory inspection of the code.

This is around mapgd.c:3691:

unsigned char *msSaveImageBufferGD(gdImagePtr img, int *size_ptr,
outputFormatObj *format)
{
  unsigned char *imgbytes;
  // ...
    if( force_palette ) {
      gdImagePtr gdPImg;
      const char *palette = msGetOutputFormatOption( format, "PALETTE",
"palette.txt");

      gdPImg = msImageCreateWithPaletteGD(img, palette, gdImageSX(img),
gdImageSY(img));

      msImageCopyForcePaletteGD(img, gdPImg);
      imgbytes = gdImagePngPtr(gdPImg, size_ptr);
    }
  // ...
  return imgbytes;
}

the (gdImagePtr gdPImg) is a pointer to the bytes created by the gd code.

But what is returned to mapscript (see the function below from around
mapscript_wrap.c:2581), is the (unsigned char *imgbytes) above.

SWIGINTERN gdBuffer imageObj_getBytes(imageObj *self){
        // ...
        buffer.data = msSaveImageBuffer(self, &buffer.size, self->format);
        // ...
        return buffer;
    }

so when the JNI wrapper calls gdFree() at mapscript_wrap.c:25804:

JNIEXPORT jbyteArray JNICALL
Java_edu_umn_gis_mapscript_mapscriptJNI_imageObj_1getBytes(JNIEnv *jenv,
jclass jcls, jlong jarg1) {
  jbyteArray jresult = 0 ;
  // ...
    result = imageObj_getBytes(arg1);
  // ..
  jresult = SWIG_JavaArrayOutSchar(jenv, (&result)->data, (&result)->size); 
  if( (&result)->owns_data ) gdFree((&result)->data); 
  return jresult;
}

it's only the (unsigned char *imgbytes) from above (mapgd.c) that gets
freed,
leaking the original (gdImagePtr gdPImg) allocated by the gd code.

At least that's my guess, still exploring further.

Perhaps I should try to recreate this as a self contained test case, and
then
I could file a bug.

- Rich

-- 
View this message in context: http://www.nabble.com/thread-safety-tp15514019p15622039.html
Sent from the Mapserver - User mailing list archive at Nabble.com.




More information about the MapServer-users mailing list