[SOLVED] PingBlob memory leak?

The MagickWand interface is a new high-level C API interface to ImageMagick core methods. We discourage the use of the core methods and encourage the use of this API instead. Post MagickWand questions, bug reports, and suggestions to this forum.
Post Reply
pete
Posts: 4
Joined: 2011-06-28T22:52:20-07:00
Authentication code: 8675308

[SOLVED] PingBlob memory leak?

Post by pete »

I wrote simple code, it's do simple work, call PingBlob in infinite loop. I think all resources are freed correctly but i see increasing memory usage. Checked on two machines. Maybe i doing something wrong - problem apears only with animated gifs.

Compilation:

Code: Select all

gcc -Wall -Wextra -O2 -g -I /usr/include/ImageMagick/ -o pingblob pingblob.c -lMagickCore -lpng -ljpeg -ltiff -lbz2 -lz -lm -lpthread
GIF (animated!): http://i51.tinypic.com/2vttwsj.gif
or (animated!): http://www.changethethought.com/wp-cont ... o1_500.gif

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>

#include <wand/MagickWand.h>

int main(int argc, char** argv)
{
	if (argc != 2) {
		fprintf(stderr, "usage: %s <path>\n", argv[0]);
		return 1;
	}

	char* path = argv[1];

	int fd = open(path, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "open(%s) %d, %s\n", path, errno, strerror(errno));
		return 1;
	}

	struct stat st;
	if (fstat(fd, &st)) {
		fprintf(stderr, "stat(%s) %d, %s\n", path, errno, strerror(errno));
		return 1;
	}
	
	size_t pos = 0, size = st.st_size;
	char* data = (char*)malloc(size);

	while (pos < size) {
		int r = read(fd, data + pos, size - pos);
		if (r < 0) {
			if (errno == EINTR) continue;
			fprintf(stderr, "read(%s) %d, %s\n", path, errno, strerror(errno));
			return 1;
		}

		pos += r;
	}

	close(fd);

	MagickCoreGenesis(".", MagickFalse);

	while (1) {
		ImageInfo* ii = CloneImageInfo(NULL);
		ExceptionInfo ei;
		GetExceptionInfo(&ei);

		Image* img = PingBlob(ii, data, size, &ei);
		DestroyImageInfo(ii);
		
		fprintf(stderr, "PingBlob: %d, %s, %s\n", 
				ei.severity, ei.reason, ei.description);

		DestroyExceptionInfo(&ei);

		if (!img) break;

		fprintf(stderr, "PingBlob: %s, %lu x %lu, %lu COLORS, %lu DEPTH\n",
				img->magick, img->magick_columns, img->magick_rows, img->colors, img->depth);

		DestroyImage(img);
		usleep(10000);
	}

	free(data);
	MagickCoreTerminus();
	return 0;
}

Code: Select all

$ while true ; do ps cux | grep pingblob ; sleep 1s ; done
521      24386  8.0  0.1  31196 19856 pts/107  S+   22:28   0:00 pingblob
521      24386  8.0  0.2  48404 36996 pts/107  R+   22:28   0:00 pingblob
521      24386  8.3  0.3  66164 54756 pts/107  S+   22:28   0:00 pingblob
521      24386  8.5  0.4  83924 72516 pts/107  S+   22:28   0:00 pingblob
521      24386  8.6  0.5 101272 89864 pts/107  S+   22:28   0:00 pingblob
521      24386  8.6  0.6 118756 107416 pts/107 S+   22:28   0:00 pingblob
521      24386  8.5  0.7 136104 124764 pts/107 S+   22:28   0:00 pingblob
521      24386  8.6  0.8 153724 142316 pts/107 S+   22:28   0:00 pingblob
521      24386  8.5  0.9 171212 159872 pts/107 S+   22:28   0:00 pingblob
521      24386  8.7  1.0 188972 177632 pts/107 S+   22:28   0:00 pingblob
521      24386  8.6  1.1 206316 195024 pts/107 R+   22:28   0:00 pingblob
521      24386  8.6  1.2 224076 212736 pts/107 S+   22:28   0:01 pingblob
521      24386  8.6  1.4 241836 230496 pts/107 S+   22:28   0:01 pingblob
521      24386  8.6  1.5 259600 248256 pts/107 S+   22:28   0:01 pingblob
521      24386  8.6  1.6 277220 265812 pts/107 S+   22:28   0:01 pingblob
521      24386  8.6  1.7 294704 283364 pts/107 S+   22:28   0:01 pingblob
521      24386  8.7  1.8 312328 300920 pts/107 S+   22:28   0:01 pingblob
521      24386  8.6  1.9 329812 318472 pts/107 S+   22:28   0:01 pingblob
521      24386  8.2  2.0 347848 336476 pts/107 R+   22:28   0:01 pingblob
521      24386  8.2  2.1 365608 354200 pts/107 S+   22:28   0:01 pingblob
521      24386  8.3  2.2 383368 371960 pts/107 S+   22:28   0:01 pingblob
521      24386  8.3  2.3 400852 389512 pts/107 S+   22:28   0:01 pingblob
521      24386  8.3  2.4 418200 406860 pts/107 R+   22:28   0:02 pingblob
Last edited by pete on 2012-01-07T15:40:10-07:00, edited 1 time in total.
pete
Posts: 4
Joined: 2011-06-28T22:52:20-07:00
Authentication code: 8675308

Re: PingBlob memory leak?

Post by pete »

If i replace PingBlob by BlobToImage, memory usage increase too.

I forgot, checked with: ImageMagick-6.7.3-7 and 6.6.0-4


And... SOLVED! I, think...

Code: Select all

                do { 
                        Image* next = img->next;
                        DestroyImage(img);
                        img = next;
                } while (img != NULL);
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: PingBlob memory leak?

Post by anthony »

pete wrote:If i replace PingBlob by BlobToImage, memory usage increase too.

I forgot, checked with: ImageMagick-6.7.3-7 and 6.6.0-4


And... SOLVED! I, think...

Code: Select all

                do { 
                        Image* next = img->next;
                        DestroyImage(img);
                        img = next;
                } while (img != NULL);
You can also do..

Code: Select all

   img = DestroyImageList(img);
but as you are using wands, you could just destroy the wand holding the images with DestroyMagickWand()
Or ClearMagickWand() to remove all images and settings without destroying the wand itself (just reset it completely)

Or you can delete the Current images from the Wand until there are no more images in the wand.

Code: Select all

   while( MagickSetIteratorIndex(wand,0) != MagickFalse ) {
       \\ do things with current image
       MagickRemoveImage( wand );
ASIDE: I have just made GetImageFromList() a bit more efficient (in IMv6.7.5-1) by stopping it needing to determine the actual list length to deal with the index value. Minor but did it while I was looking at the code.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply