Page 1 of 1

What is the proper way to uninitialize ImageMagick with Magick++?

Posted: 2014-12-05T08:34:01-07:00
by fuzion
Hello,

This is my first time post to this forum and I am a beginner ImageMagick/Magick++ user. I searched the forum for "InitializeMagick" and it found only one post at this time (that did not answer my question).

I am using Magick++ in a C++ program successfully to resize images. I am currently doing stability and performance testing and this is one of the tests that I do (to search for memory leaks):
  • - run the program via valgrind for several hours, resizing images
    - stop the program via a signal
    - inspect the valgrind output for memory leaks
Note that the program is being shutdown via a signal handler calling exit (not from the main function returning). I observe a very small amount of memory that is still accessible when the program terminates (which is allocated via ImageMagick/Magick++). It does not look like an actual memory leak resulting from resizing images, but rather from me not properly cleaning up the ImageMagick library.

In the Magick++ API documentation at the following URL:
http://www.imagemagick.org/Magick++/
it states the following:
Be sure to to initialize the ImageMagick library prior to using the Magick++ library ... the InitializeMagick() function call.
I am doing this, but the documentation does not explain how Magick++ uninitializes ImageMagick.

Note in the MagickCore interface, there is a method to initialize and uninitialize the ImageMagick library:
http://www.imagemagick.org/api/magick.php

I seem to recall from the valgrind dump (which I do not have in front of me at the moment), that a call to Magick++'s InitializeMagick is actually calling MagickCoreGenesis from MagickCore. So I am guessing that I am missing the matching MagickCoreTerminus call (but I don't see any way to get to it via the Magick++ API).

Does Magick++ require proper stack unrolling where InitializeMagick was called? I am guessing that, because I am using a signal handler to terminate the process, that the main's stack (that called InitializeMagick) is not being "properly unrolled".

Here is some pseudo code as to what I am doing (as I do not have the code in front of me). Note that I have several C++ programs that work like this with absolutely no memory leak when they exit via a signal handler. Currently, only the ones that are using Magick++ have memory leaks when they exit.

Code: Select all

void signalHandler(int signum) {

  // shutdown all of the running threads gracefully

  exit(1); // this is the exit that causes process termination
}

int main (int argc, char** argv) {
  // I am guessing that this never goes "off the stack" properly, 
  // prior to the process terminating from the exit call in signalHandler
  InitializeMagick(*argv);

  // register signalHandler here for SIGINT (Ctrl-C), SIGUSR1, etc signals

  // start all of the threads (one of which is responsible for resizing images using Magick++)

  // infinite loop here on purpose
  while (true) {
    sleep(1);
  }

  exit(1); // execution never reaches here
}
Should I mix MagickCore and Magick++? I'm thinking to try my next test where I use MagickCore in main to call MagickCoreGenesis, and then call MagickCoreTerminus in the signal handler. The thread that does image resizing should still be able to use Magick++.

Sorry that I don't have any of the valgrind output in front of me at the moment. I can get this later today.

Many thanks!

Re: What is the proper way to uninitialize ImageMagick with Magick++?

Posted: 2014-12-05T08:51:25-07:00
by dlemstra
You can use the TerminateMagick method to cleanup the memory. Please let us know if you find something that is not properly released.

Re: What is the proper way to uninitialize ImageMagick with Magick++?

Posted: 2014-12-18T08:54:52-07:00
by fuzion
I'll give TerminateMagick a try next.

I just tried (prior to seeing your response) using the following:

Code: Select all

#include <magick/MagickCore.h>
// ...
MagickCore::MagickCoreTerminus(); // before process exits
// ...
MagickCoreGenesis(*argv, MagickTrue); // in main after process starts
When I do this, I get the following "still reachable" memory reported by valgrind. Note, exitDataStoreNode is my signal handler that calls MagickCore::MagickCoreTerminus().

Code: Select all

==14762== HEAP SUMMARY:
==14762==     in use at exit: 328 bytes in 9 blocks
==14762==   total heap usage: 22,989 allocs, 22,980 frees, 64,166,372 bytes allocated
==14762== 
==14762== 7 bytes in 1 blocks are still reachable in loss record 1 of 9
==14762==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==14762==    by 0x7304AE8: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7306966: try_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7307681: lt_dlopenadvise (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304A27: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x54AE189: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AEDEC: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54A952E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x42D07F: main (main.cpp:226)
==14762== 
==14762== 9 bytes in 1 blocks are still reachable in loss record 2 of 9
==14762==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==14762==    by 0x7304AE8: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304B83: lt__memdup (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x73051D4: tryall_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x730728D: try_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7307681: lt_dlopenadvise (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304A27: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x54AE189: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AEDEC: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54A952E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x42D07F: main (main.cpp:226)
==14762== 
==14762== 16 bytes in 1 blocks are still reachable in loss record 3 of 9
==14762==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==14762==    by 0x73083CD: lt__slist_box (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304C64: lt_dlloader_add (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7306053: loader_init.constprop.8 (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7306126: lt_dlinit (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x54AE189: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AEDEC: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54A952E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x42D07F: main (main.cpp:226)
==14762== 
==14762== 16 bytes in 1 blocks are still reachable in loss record 4 of 9
==14762==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==14762==    by 0x7304AE8: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304B1D: lt__zalloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304929: lt_dlpreload (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x730613B: lt_dlinit (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x54AE189: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AEDEC: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54A952E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x42D07F: main (main.cpp:226)
==14762== 
==14762== 16 bytes in 1 blocks are still reachable in loss record 5 of 9
==14762==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==14762==    by 0x73083CD: lt__slist_box (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304C64: lt_dlloader_add (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7306053: loader_init.constprop.8 (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304A36: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x54AE189: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AEDEC: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54A952E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x42D07F: main (main.cpp:226)
==14762== 
==14762== 32 bytes in 1 blocks are still reachable in loss record 6 of 9
==14762==    at 0x4C2B030: calloc (vg_replace_malloc.c:623)
==14762==    by 0x940162F: _dlerror_run (in /lib64/libdl-2.20.so)
==14762==    by 0x940111E: dlclose (in /lib64/libdl-2.20.so)
==14762==    by 0x730861B: vm_close (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x730647C: lt_dlclose (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x54AD930: DestroyModuleNode (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x5515914: DestroySplayTree (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AE340: DestroyModuleList (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AEE22: ModuleComponentTerminus (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54A9754: MagickCoreTerminus (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x42CFF8: exitDataStoreNode(int, siginfo_t*, void*) (main.cpp:213)
==14762==    by 0x70F6D2F: ??? (in /lib64/libpthread-2.20.so)
==14762== 
==14762== 72 bytes in 1 blocks are still reachable in loss record 7 of 9
==14762==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==14762==    by 0x7304AE8: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304B1D: lt__zalloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x73048C9: preopen_LTX_get_vtable (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7306041: loader_init.constprop.8 (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7306126: lt_dlinit (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x54AE189: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AEDEC: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54A952E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x42D07F: main (main.cpp:226)
==14762== 
==14762== 72 bytes in 1 blocks are still reachable in loss record 8 of 9
==14762==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==14762==    by 0x7304AE8: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304B1D: lt__zalloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7308731: dlopen_LTX_get_vtable (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7306041: loader_init.constprop.8 (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304A36: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x54AE189: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AEDEC: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54A952E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x42D07F: main (main.cpp:226)
==14762== 
==14762== 88 bytes in 1 blocks are still reachable in loss record 9 of 9
==14762==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==14762==    by 0x7304AE8: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304B1D: lt__zalloc (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7307207: try_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7307681: lt_dlopenadvise (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x7304A27: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==14762==    by 0x54AE189: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54AEDEC: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x54A952E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==14762==    by 0x42D07F: main (main.cpp:226)
==14762== 
==14762== LEAK SUMMARY:
==14762==    definitely lost: 0 bytes in 0 blocks
==14762==    indirectly lost: 0 bytes in 0 blocks
==14762==      possibly lost: 0 bytes in 0 blocks
==14762==    still reachable: 328 bytes in 9 blocks
==14762==         suppressed: 0 bytes in 0 blocks
==14762== 
==14762== For counts of detected and suppressed errors, rerun with: -v
==14762== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Re: What is the proper way to uninitialize ImageMagick with Magick++?

Posted: 2014-12-18T09:18:02-07:00
by fuzion
Unfortunately it wouldn't compile:

Code: Select all

main.cpp: In function 'void exitDataStoreNode(int, siginfo_t*, void*)':
main.cpp:214:18: error: 'TerminateMagick' was not declared in this scope
  TerminateMagick();
// Note: If I comment out TerminateMagick(); it compiles just fine, with InitializeMagick(*argv);
So next I'll try using a global variable that the signal handler sets to true. The main function should exit its loop when it detects that this global is set to true, and then the stack that InitializeMagick(*argv); was called on should be unwound gracefully. I should know soon whether this helped or not.

Re: What is the proper way to uninitialize ImageMagick with Magick++?

Posted: 2014-12-18T09:28:21-07:00
by dlemstra
I apologize, TerminateMagick as only added to ImageMagick 7. You should just call 'MagickCore::MagickCoreTerminus();' for now. I will take a look at the report from valgrind to see if we are still forgetting to clean something up. Are you linking with the latest ImageMagick 6 version?

Re: What is the proper way to uninitialize ImageMagick with Magick++?

Posted: 2014-12-18T11:14:47-07:00
by fuzion
Unfortunately, having the main function return instead of calling exit in the signal handler didn't help. In fact it got worse. Now there's 3,306 bytes still reachable.

Re: What is the proper way to uninitialize ImageMagick with Magick++?

Posted: 2014-12-18T11:16:28-07:00
by fuzion
Sorry, I should have posted what version I'm using. I'm' using Gentoo and currently have version 6.8.9.7 installed.

I just tried the first example in the documentation/API and it gives me memory leaks as well.

Code: Select all

http://www.imagemagick.org/Magick++/Image.html

Re: What is the proper way to uninitialize ImageMagick with Magick++?

Posted: 2014-12-18T11:43:38-07:00
by fuzion
I just installed ImageMagick 6.9.0.0 (the latest available stable version on Gentoo). I am using Valgrind version 3.10.1 (the latest available stable version on Gentoo).

Here is the test program that I am using, based on the API documentation for Image:

Code: Select all

#include <Magick++.h> 
#include <iostream> 
using namespace std; 
using namespace Magick; 
int main(int argc,char **argv) 
{ 
  if (argc != 2) {
    printf("You must specify a filename to open.\n");
    printf("Usage: ./memoryleaktest2 filename.jpg\n");
    exit (0);
  }

  InitializeMagick(*argv);

  // Construct the image object. Separating image construction from the 
  // the read operation ensures that a failure to read the image file 
  // doesn't render the image object useless. 
  Image image;
  try { 
    // Read a file into image object 
    image.read( argv[1] );

    // Crop the image to specified size (width, height, xOffset, yOffset)
    image.crop( Geometry(100,100, 100, 100) );

    // Write the image to a file 
    image.write( "x.gif" ); 
  } 
  catch( Exception &error_ ) 
  { 
    cout << "Caught exception: " << error_.what() << endl; 
    return 1; 
  }

  return 0; 
}
This is the Makefile that I'm using to compile the program (I just enter make to compile it):

Code: Select all

PWD=$(shell pwd)

all:
	c++ -g -o memoryleaktest2 $(PWD)/memoryleaktest2.cpp `Magick++-config --cppflags --cxxflags --ldflags --libs`
This is how I'm running the program with valgrind:

Code: Select all

valgrind --leak-check=full --show-leak-kinds=all --log-file=valgrind.txt ./memoryleaktest2 widescreen.jpg
Note: widescreen.jpg is 1920x1200 pixel JPEG image (1,103,310 bytes).

Here is the output that I get from valgrind:

Code: Select all

==31659== Memcheck, a memory error detector
==31659== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==31659== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==31659== Command: ./memoryleaktest2 widescreen.jpg
==31659== Parent PID: 2573
==31659== 
==31659== 
==31659== HEAP SUMMARY:
==31659==     in use at exit: 6,845 bytes in 25 blocks
==31659==   total heap usage: 2,114 allocs, 2,089 frees, 153,756,718 bytes allocated
==31659== 
==31659== 7 bytes in 1 blocks are still reachable in loss record 1 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x7487A38: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7489796: try_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x748A3AD: lt_dlopenadvise (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487977: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x55051E9: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5505E4C: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x550058E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E86B0A: Magick::InitializeMagick(char const*) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x401101: main (memoryleaktest2.cpp:13)
==31659== 
==31659== 9 bytes in 1 blocks are still reachable in loss record 2 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x7487A38: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487AEB: lt__memdup (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x74886E4: tryall_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7489F87: try_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x748A3AD: lt_dlopenadvise (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487977: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x55051E9: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5505E4C: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x550058E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E86B0A: Magick::InitializeMagick(char const*) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x401101: main (memoryleaktest2.cpp:13)
==31659== 
==31659== 16 bytes in 1 blocks are still reachable in loss record 3 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x748B2DD: lt__slist_box (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487BE4: lt_dlloader_add (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x748906B: loader_init.constprop.7 (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7489156: lt_dlinit (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x55051E9: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5505E4C: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x550058E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E86B0A: Magick::InitializeMagick(char const*) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x401101: main (memoryleaktest2.cpp:13)
==31659== 
==31659== 16 bytes in 1 blocks are still reachable in loss record 4 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x7487A38: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487A75: lt__zalloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487879: lt_dlpreload (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x748916B: lt_dlinit (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x55051E9: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5505E4C: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x550058E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E86B0A: Magick::InitializeMagick(char const*) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x401101: main (memoryleaktest2.cpp:13)
==31659== 
==31659== 16 bytes in 1 blocks are still reachable in loss record 5 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x748B2DD: lt__slist_box (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487BE4: lt_dlloader_add (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x748906B: loader_init.constprop.7 (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487986: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x55051E9: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5505E4C: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x550058E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E86B0A: Magick::InitializeMagick(char const*) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x401101: main (memoryleaktest2.cpp:13)
==31659== 
==31659== 24 bytes in 1 blocks are still reachable in loss record 6 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x4C2B2DF: realloc (vg_replace_malloc.c:692)
==31659==    by 0x5E8C7F8: ??? (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.3/libgomp.so.1.0.0)
==31659==    by 0x5E909FA: ??? (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.3/libgomp.so.1.0.0)
==31659==    by 0x55850DD: CropImage (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E8AB10: Magick::Image::crop(Magick::Geometry const&) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x4011A3: main (memoryleaktest2.cpp:24)
==31659== 
==31659== 25 bytes in 1 blocks are still reachable in loss record 7 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x4005021: local_strdup (in /lib64/ld-2.19.so)
==31659==    by 0x4008344: _dl_map_object (in /lib64/ld-2.19.so)
==31659==    by 0x400C301: openaux (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x400C4ED: _dl_map_object_deps (in /lib64/ld-2.19.so)
==31659==    by 0x4012ABC: dl_open_worker (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x4012478: _dl_open (in /lib64/ld-2.19.so)
==31659==    by 0x78B0055: dlopen_doit (in /lib64/libdl-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x78B05FB: _dlerror_run (in /lib64/libdl-2.19.so)
==31659== 
==31659== 25 bytes in 1 blocks are still reachable in loss record 8 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x400A994: _dl_new_object (in /lib64/ld-2.19.so)
==31659==    by 0x4005E55: _dl_map_object_from_fd (in /lib64/ld-2.19.so)
==31659==    by 0x40080BC: _dl_map_object (in /lib64/ld-2.19.so)
==31659==    by 0x400C301: openaux (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x400C4ED: _dl_map_object_deps (in /lib64/ld-2.19.so)
==31659==    by 0x4012ABC: dl_open_worker (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x4012478: _dl_open (in /lib64/ld-2.19.so)
==31659==    by 0x78B0055: dlopen_doit (in /lib64/libdl-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659== 
==31659== 32 bytes in 1 blocks are still reachable in loss record 9 of 20
==31659==    at 0x4C2B030: calloc (vg_replace_malloc.c:623)
==31659==    by 0x78B066F: _dlerror_run (in /lib64/libdl-2.19.so)
==31659==    by 0x78B00F0: dlopen@@GLIBC_2.2.5 (in /lib64/libdl-2.19.so)
==31659==    by 0x748B577: vm_open (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7488769: tryall_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7488951: tryall_dlopen_module (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x748A175: try_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x748A3AD: lt_dlopenadvise (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x5506339: OpenModule (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5500CD2: GetMagickInfo (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x54F3631: SetImageInfo (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x54601C0: ReadImage (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659== 
==31659== 72 bytes in 1 blocks are still reachable in loss record 10 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x7487A38: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487A75: lt__zalloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487819: preopen_LTX_get_vtable (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7489059: loader_init.constprop.7 (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7489156: lt_dlinit (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x55051E9: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5505E4C: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x550058E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E86B0A: Magick::InitializeMagick(char const*) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x401101: main (memoryleaktest2.cpp:13)
==31659== 
==31659== 72 bytes in 1 blocks are still reachable in loss record 11 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x7487A38: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487A75: lt__zalloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x748B641: dlopen_LTX_get_vtable (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7489059: loader_init.constprop.7 (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487986: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x55051E9: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5505E4C: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x550058E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E86B0A: Magick::InitializeMagick(char const*) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x401101: main (memoryleaktest2.cpp:13)
==31659== 
==31659== 88 bytes in 1 blocks are still reachable in loss record 12 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x7487A38: lt__malloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487A75: lt__zalloc (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7489EFF: try_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x748A3AD: lt_dlopenadvise (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7487977: lt_dlpreload_open (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x55051E9: IsModuleTreeInstantiated.isra.5 (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5505E4C: ModuleComponentGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x550058E: MagickCoreGenesis (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E86B0A: Magick::InitializeMagick(char const*) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x401101: main (memoryleaktest2.cpp:13)
==31659== 
==31659== 111 bytes in 2 blocks are still reachable in loss record 13 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x4005021: local_strdup (in /lib64/ld-2.19.so)
==31659==    by 0x4008034: _dl_map_object (in /lib64/ld-2.19.so)
==31659==    by 0x4012A63: dl_open_worker (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x4012478: _dl_open (in /lib64/ld-2.19.so)
==31659==    by 0x78B0055: dlopen_doit (in /lib64/libdl-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x78B05FB: _dlerror_run (in /lib64/libdl-2.19.so)
==31659==    by 0x78B00F0: dlopen@@GLIBC_2.2.5 (in /lib64/libdl-2.19.so)
==31659==    by 0x748B577: vm_open (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7488769: tryall_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==31659== 
==31659== 111 bytes in 2 blocks are still reachable in loss record 14 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x400A994: _dl_new_object (in /lib64/ld-2.19.so)
==31659==    by 0x4005E55: _dl_map_object_from_fd (in /lib64/ld-2.19.so)
==31659==    by 0x40080BC: _dl_map_object (in /lib64/ld-2.19.so)
==31659==    by 0x4012A63: dl_open_worker (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x4012478: _dl_open (in /lib64/ld-2.19.so)
==31659==    by 0x78B0055: dlopen_doit (in /lib64/libdl-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x78B05FB: _dlerror_run (in /lib64/libdl-2.19.so)
==31659==    by 0x78B00F0: dlopen@@GLIBC_2.2.5 (in /lib64/libdl-2.19.so)
==31659==    by 0x748B577: vm_open (in /usr/lib64/libltdl.so.7.3.0)
==31659== 
==31659== 192 bytes in 1 blocks are still reachable in loss record 15 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x5E8C7A8: ??? (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.3/libgomp.so.1.0.0)
==31659==    by 0x5E90B8E: ??? (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.3/libgomp.so.1.0.0)
==31659==    by 0x55850DD: CropImage (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E8AB10: Magick::Image::crop(Magick::Geometry const&) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x4011A3: main (memoryleaktest2.cpp:24)
==31659== 
==31659== 304 bytes in 1 blocks are possibly lost in loss record 16 of 20
==31659==    at 0x4C2B030: calloc (vg_replace_malloc.c:623)
==31659==    by 0x4011069: allocate_dtv (in /lib64/ld-2.19.so)
==31659==    by 0x401178D: _dl_allocate_tls (in /lib64/ld-2.19.so)
==31659==    by 0x62B5E91: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.19.so)
==31659==    by 0x5E90905: ??? (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.3/libgomp.so.1.0.0)
==31659==    by 0x55850DD: CropImage (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E8AB10: Magick::Image::crop(Magick::Geometry const&) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x4011A3: main (memoryleaktest2.cpp:24)
==31659== 
==31659== 528 bytes in 3 blocks are still reachable in loss record 17 of 20
==31659==    at 0x4C2B030: calloc (vg_replace_malloc.c:623)
==31659==    by 0x40101CD: _dl_check_map_versions (in /lib64/ld-2.19.so)
==31659==    by 0x4012F52: dl_open_worker (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x4012478: _dl_open (in /lib64/ld-2.19.so)
==31659==    by 0x78B0055: dlopen_doit (in /lib64/libdl-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x78B05FB: _dlerror_run (in /lib64/libdl-2.19.so)
==31659==    by 0x78B00F0: dlopen@@GLIBC_2.2.5 (in /lib64/libdl-2.19.so)
==31659==    by 0x748B577: vm_open (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7488769: tryall_dlopen (in /usr/lib64/libltdl.so.7.3.0)
==31659==    by 0x7488951: tryall_dlopen_module (in /usr/lib64/libltdl.so.7.3.0)
==31659== 
==31659== 1,182 bytes in 1 blocks are still reachable in loss record 18 of 20
==31659==    at 0x4C2B030: calloc (vg_replace_malloc.c:623)
==31659==    by 0x400A746: _dl_new_object (in /lib64/ld-2.19.so)
==31659==    by 0x4005E55: _dl_map_object_from_fd (in /lib64/ld-2.19.so)
==31659==    by 0x40080BC: _dl_map_object (in /lib64/ld-2.19.so)
==31659==    by 0x400C301: openaux (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x400C4ED: _dl_map_object_deps (in /lib64/ld-2.19.so)
==31659==    by 0x4012ABC: dl_open_worker (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x4012478: _dl_open (in /lib64/ld-2.19.so)
==31659==    by 0x78B0055: dlopen_doit (in /lib64/libdl-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659== 
==31659== 1,568 bytes in 1 blocks are still reachable in loss record 19 of 20
==31659==    at 0x4C28F40: malloc (vg_replace_malloc.c:296)
==31659==    by 0x5E8C7A8: ??? (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.3/libgomp.so.1.0.0)
==31659==    by 0x5E904D5: ??? (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.3/libgomp.so.1.0.0)
==31659==    by 0x5E8F47B: GOMP_parallel_start (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.3/libgomp.so.1.0.0)
==31659==    by 0x54F1946: SyncImage (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5531788: AssignImageColors (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5532145: QuantizeImage (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x5427B6D: SetImageType (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0xA2EB0A0: WriteGIFImage (in /usr/lib64/ImageMagick-6.9.0/modules-Q16/coders/gif.so)
==31659==    by 0x5461861: WriteImage (in /usr/lib64/libMagickCore-6.Q16.so.2.0.0)
==31659==    by 0x4E90ED9: Magick::Image::write(std::string const&) (in /usr/lib64/libMagick++-6.Q16.so.5.0.0)
==31659==    by 0x4011E3: main (memoryleaktest2.cpp:27)
==31659== 
==31659== 2,447 bytes in 2 blocks are still reachable in loss record 20 of 20
==31659==    at 0x4C2B030: calloc (vg_replace_malloc.c:623)
==31659==    by 0x400A746: _dl_new_object (in /lib64/ld-2.19.so)
==31659==    by 0x4005E55: _dl_map_object_from_fd (in /lib64/ld-2.19.so)
==31659==    by 0x40080BC: _dl_map_object (in /lib64/ld-2.19.so)
==31659==    by 0x4012A63: dl_open_worker (in /lib64/ld-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x4012478: _dl_open (in /lib64/ld-2.19.so)
==31659==    by 0x78B0055: dlopen_doit (in /lib64/libdl-2.19.so)
==31659==    by 0x400E8CF: _dl_catch_error (in /lib64/ld-2.19.so)
==31659==    by 0x78B05FB: _dlerror_run (in /lib64/libdl-2.19.so)
==31659==    by 0x78B00F0: dlopen@@GLIBC_2.2.5 (in /lib64/libdl-2.19.so)
==31659==    by 0x748B577: vm_open (in /usr/lib64/libltdl.so.7.3.0)
==31659== 
==31659== LEAK SUMMARY:
==31659==    definitely lost: 0 bytes in 0 blocks
==31659==    indirectly lost: 0 bytes in 0 blocks
==31659==      possibly lost: 304 bytes in 1 blocks
==31659==    still reachable: 6,541 bytes in 24 blocks
==31659==         suppressed: 0 bytes in 0 blocks
==31659== 
==31659== For counts of detected and suppressed errors, rerun with: -v
==31659== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)