From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Tassilo Horn Newsgroups: gmane.emacs.devel Subject: Re: Using the ImageMagick backend seems to leak memory Date: Tue, 11 Jan 2011 10:53:24 +0100 Message-ID: <878vyrpy0b.fsf@member.fsf.org> References: <87sjx6zczl.fsf@member.fsf.org> <877heca0s8.fsf@member.fsf.org> <87lj2rq12b.fsf@member.fsf.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1294740126 16953 80.91.229.12 (11 Jan 2011 10:02:06 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 11 Jan 2011 10:02:06 +0000 (UTC) Cc: emacs-devel@gnu.org To: joakim@verona.se Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Jan 11 11:02:02 2011 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Pcb39-0004oK-CY for ged-emacs-devel@m.gmane.org; Tue, 11 Jan 2011 11:02:00 +0100 Original-Received: from localhost ([127.0.0.1]:59324 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pcax2-00080p-9x for ged-emacs-devel@m.gmane.org; Tue, 11 Jan 2011 04:55:40 -0500 Original-Received: from [140.186.70.92] (port=42910 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PcawA-0007Un-7J for emacs-devel@gnu.org; Tue, 11 Jan 2011 04:55:30 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Pcaut-0006QA-D5 for emacs-devel@gnu.org; Tue, 11 Jan 2011 04:53:29 -0500 Original-Received: from deliver.uni-koblenz.de ([141.26.64.15]:10225) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Pcaut-0006PV-53 for emacs-devel@gnu.org; Tue, 11 Jan 2011 04:53:27 -0500 Original-Received: from localhost (localhost [127.0.0.1]) by deliver.uni-koblenz.de (Postfix) with ESMTP id C153678014B2; Tue, 11 Jan 2011 10:53:25 +0100 (CET) Original-Received: from deliver.uni-koblenz.de ([127.0.0.1]) by localhost (deliver.uni-koblenz.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 11476-05; Tue, 11 Jan 2011 10:53:24 +0100 (CET) X-CHKRCPT: Envelopesender noch tassilo@member.fsf.org Original-Received: from thinkpad (tsdh.uni-koblenz.de [141.26.67.142]) by deliver.uni-koblenz.de (Postfix) with ESMTP id A2AC67801306; Tue, 11 Jan 2011 10:53:24 +0100 (CET) In-Reply-To: (joakim@verona.se's message of "Tue, 11 Jan 2011 10:35:47 +0100") User-Agent: Gnus/5.110011 (No Gnus v0.11) Emacs/24.0.50 (gnu/linux) X-Virus-Scanned: amavisd-new at uni-koblenz.de X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:134440 Archived-At: joakim@verona.se writes: Hi Joakim, >> this is driving me nuts. I've already tried modifying >> imagemagick_load_image() with some messages, and so that it always >> does MagickWandGenesis() first and MagickWandTerminus() after >> destroying the last MagickWand. It does so, but that didn't help... [patch below] >> One strangeness I found is the line >> >> image_error ("im read failed", Qnil, Qnil); >> >> which is called unconditionally in imagemagick_load_image(). Why? > > Thats supposed to be an error condition exit only. > Isnt there a return statement before? No, neither before nor after. > I havent yet tried to recreate your problem, but my experience when I > worked on the patch was that I got memory issues when working with > image bundle files. That's not the case here. I load one single PNG (or whatever) file, or in the case of doc-view, several PNG files one after the other. > Also the imagemagick team was very helpful in providing fixes in their > code. I tried to get in contact, but my posting via Gmane was rejected and I got no response on ##imagemagick. Then I tried to register with their web forum, but I still haven't got the confirmation mail... > Have you tried to install a development version of imagemagick? No, I'm running the released version 6.6.5.6. And as I've said in another mail, the MagickWand example code with my small changes works just fine with that version, i.e., memory is given back... And the basic order of MagickWand function invocations applied in emacs seems to match the example. Maybe some emacs/X structures share data with MagickWand structures, so that the latter cannot be freed when destroying the MagickWand or calling MagickWandTerminus? Bye, Tassilo Here's a patch with my unsuccessful changes to image.c. Maybe it's of some use... --8<---------------cut here---------------start------------->8--- === modified file 'src/image.c' --- src/image.c 2011-01-07 22:33:32 +0000 +++ src/image.c 2011-01-11 08:11:07 +0000 @@ -7521,9 +7521,12 @@ image. Interface :index is same as for GIF. First we "ping" the image to see how many sub-images it contains. Pinging is faster than loading the image to find out things about it. */ + MagickWandGenesis (); + message ("MagickWandGenesis ();"); image = image_spec_value (img->spec, QCindex, NULL); ino = INTEGERP (image) ? XFASTINT (image) : 0; ping_wand = NewMagickWand (); + message ("ping_wand = NewMagickWand ();"); MagickSetResolution (ping_wand, 2, 2); if (filename != NULL) { @@ -7539,6 +7542,7 @@ image_error ("Invalid image number `%s' in image `%s'", image, img->spec); DestroyMagickWand (ping_wand); + message ("DestroyMagickWand (ping_wand);"); return 0; } @@ -7549,6 +7553,9 @@ img->data.lisp_val)); DestroyMagickWand (ping_wand); + message ("DestroyMagickWand (ping_wand);"); + + /* Now, after pinging, we know how many images are inside the file. If its not a bundle, just one. */ @@ -7566,6 +7573,7 @@ if (im_image != NULL) { image_wand = NewMagickWandFromImage (im_image); + message ("image_wand = NewMagickWand ();"); status = MagickTrue; } else @@ -7574,6 +7582,7 @@ else { image_wand = NewMagickWand (); + message ("image_wand = NewMagickWand ();"); status = MagickReadImageBlob (image_wand, contents, size); } image_error ("im read failed", Qnil, Qnil); @@ -7805,11 +7814,18 @@ /* Final cleanup. image_wand should be the only resource left. */ DestroyMagickWand (image_wand); + message ("DestroyMagickWand (image_wand);"); + MagickWandTerminus (); + message ("MagickWandTerminus ();"); return 1; imagemagick_error: DestroyMagickWand (image_wand); + message ("Error case: DestroyMagickWand (image_wand);"); + MagickWandTerminus (); + message ("MagickWandTerminus ();"); + /* TODO more cleanup. */ image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil); return 0; @@ -8681,8 +8697,6 @@ #if defined (HAVE_IMAGEMAGICK) if (EQ (type, Qimagemagick)) { - /* MagickWandGenesis() initializes the imagemagick library. */ - MagickWandGenesis (); return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions, libraries); } --8<---------------cut here---------------end--------------->8---