Temp Files not being closed and deleted
Posted: 2008-07-16T08:57:02-07:00
We have an application that uses ImageMagick to manipulate many (possibly thousands) of images in a batch mode, and have come across a problem that ImageMagick temporary files are not being properly cleaned up, and eventually we will get an error for 'Too Many Open Files'.
It appears as if the old version (around Ver 6.2.6-Q16) worked fine, but this has been an issue for all version since then, including the current 6.4.2 release.
I have taken the liberty of trying to debug this issue, and believe I have found the problem.
The bug appears in our code when we execute the following line of code:
tiffimg.write(poblob);
where tiffimg is an Image and poblob is a pointer to a Blob.
The Image is a .TIFF image, that may cause a warning such as 'tags not sorted in ascending order', which as far as our program is concerned, is ok and not a problem.
Tracing into the write() function, the bug appears to be in the ‘CloseBlob’ function, around line 473 of the file blob.c (based on the 6.4.1-10 build for Windows), where it currently reads:
if (image->blob->exempt != MagickFalse)
{
image->blob->type=UndefinedStream;
return(MagickTrue);
}
If this if() condition is true, then it seems to return from the CloseBlob() function prematurely, without first closing the file associated with this blob, as it otherwise would do further down in the function, in that same file at line 516.
status=fclose(image->blob->file);
Later, after returning from the CloseBlob() function, an attempt is made to delete this temporary file, but that delete fails with an ‘Access’ error, because the operating system cannot delete the file while it is still open. That is why the temporary files are not deleted, and also why we end up having too many files open after processing many images.
By being sure to always call the fclose() function before returning from CloseBlob(), the problem seems to be fixed.
Is there any reason that if() clause is not located further down in the CloseBlob() function, after the file is closed, or a reason why the file is not closed if the if() condition is true? It does seem to me that the file should always be closed in CloseBlob() no matter what, and the fact that there is a code path that does not close it is a bug. No?
And Is there a way we can get a fix for this incorporated into the next release of ImageMagick?
Thank you,
Robert E. Lee
GeneralHQ
It appears as if the old version (around Ver 6.2.6-Q16) worked fine, but this has been an issue for all version since then, including the current 6.4.2 release.
I have taken the liberty of trying to debug this issue, and believe I have found the problem.
The bug appears in our code when we execute the following line of code:
tiffimg.write(poblob);
where tiffimg is an Image and poblob is a pointer to a Blob.
The Image is a .TIFF image, that may cause a warning such as 'tags not sorted in ascending order', which as far as our program is concerned, is ok and not a problem.
Tracing into the write() function, the bug appears to be in the ‘CloseBlob’ function, around line 473 of the file blob.c (based on the 6.4.1-10 build for Windows), where it currently reads:
if (image->blob->exempt != MagickFalse)
{
image->blob->type=UndefinedStream;
return(MagickTrue);
}
If this if() condition is true, then it seems to return from the CloseBlob() function prematurely, without first closing the file associated with this blob, as it otherwise would do further down in the function, in that same file at line 516.
status=fclose(image->blob->file);
Later, after returning from the CloseBlob() function, an attempt is made to delete this temporary file, but that delete fails with an ‘Access’ error, because the operating system cannot delete the file while it is still open. That is why the temporary files are not deleted, and also why we end up having too many files open after processing many images.
By being sure to always call the fclose() function before returning from CloseBlob(), the problem seems to be fixed.
Is there any reason that if() clause is not located further down in the CloseBlob() function, after the file is closed, or a reason why the file is not closed if the if() condition is true? It does seem to me that the file should always be closed in CloseBlob() no matter what, and the fact that there is a code path that does not close it is a bug. No?
And Is there a way we can get a fix for this incorporated into the next release of ImageMagick?
Thank you,
Robert E. Lee
GeneralHQ