Skip to content

Instantly share code, notes, and snippets.

@zhangyuchi
Last active August 29, 2015 14:10
Show Gist options
  • Save zhangyuchi/14819bba281005305d6d to your computer and use it in GitHub Desktop.
Save zhangyuchi/14819bba281005305d6d to your computer and use it in GitHub Desktop.
image magick memory leak
unsigned char *ping_pixels;
ping_pixels=(unsigned char *) NULL;
if (setjmp(png_jmpbuf(ping)))
{
/*
PNG image is corrupt.
*/
png_destroy_read_struct(&ping,&ping_info,&end_info);
#ifdef PNG_SETJMP_NOT_THREAD_SAFE
UnlockSemaphoreInfo(ping_semaphore);
#endif
if (ping_pixels != (unsigned char *) NULL)
ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
/*
这里ping_pixels就是引起泄露的资源,是在这之后的代码中分配的,因此一开始初始化为NULL,作者原意是要在之后如果通过longjmp回来之后对其进行释放。关键就在这里,longjmp返回之后,ping_pixels的值是多少?查看了相关资料,并且通过做简单的小实验之后总结如下:
放在内存中的变量,在longjmp返回时,仍然是调用longjmp这时候的值;而如果是放在寄存器中的变量,通过longjmp返回的时候,它的值会恢复成原来setjmp的时候的值。
这在《UNIX环境高级编程》一书中讲得非常清楚。
因此,这里我目前的解决方法是将ping_pixels变量的值变成volatile,这样gcc在优化时就不会将其放到寄存器中,也就不会在longjmp返回的时候恢复其为NULL。这里注意应该使用
unsigned char * volatile ping_pixels,而不是 volatile unsigned char* ping_pixels。
经过验证,这样修改之后,这个内存泄露就修复了。
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment