<2022-03-30 Wed>
一个低级错误引发的core dumped
当将图片不断缩小到宽高为1x1
时会出现如下问题:
gm: magick/image.c:1407: DestroyImage: Assertion `image->signature == MagickSignature' failed.
Aborted (core dumped)
这是因为在ComputeResizeImage()
函数中当缩小到1x1
时失败,outputReady
为0
导致DestroyImage(filteredImage);
的调用,但是在销毁filteredImage
后并没有将其赋0
导致。
看了一下GraphicsMagick
的源码:
/*
Free memory and set pointer to NULL
*/
#define MagickFreeMemory(memory) \
{ \
void *_magick_mp=memory; \
MagickFree(_magick_mp); \
memory=0; \
}
这里明明将传入的指针赋0
了。难道这段代码不起作用?
其实这个宏是有作用的,但要看怎么使用它。因为DestroyImage()
是函数调用,实际上传入的指针是一个副本,将副本赋0
并不影响原来的值,同时也要理解宏和函数调用的不同,这里有两种情况需要考虑:
有如下测试代码:
#include <stdio.h>
#include <stdlib.h>
typedef void (*MagickFreeFunc)(void *ptr);
static MagickFreeFunc FreeFunc = free;
void MagickFree(void *memory) {
if (memory != (void *)NULL)
(FreeFunc)(memory);
}
#define MagickFreeMemory(memory) \
{ \
printf("&memory: %p\n", &memory); \
printf(" memory: %p\n", memory); \
void *_magick_mp = memory; \
MagickFree(_magick_mp); \
memory = 0; \
}
void destroy_image(char *image) { MagickFreeMemory(image); }
int main() {
char *image = (char *)malloc(1024);
printf("&image : %p\n", &image);
printf(" image : %p\n", image);
destroy_image(image);
printf("&image : %p\n", &image);
printf(" image : %p\n", image);
return 0;
}
这是GraphicsMagick
中的代码使用方式,输出如下:
% ./a.out
&image : 0x7ffc8a46dfb0
image : 0x55711df782a0
&memory: 0x7ffc8a46df88
memory: 0x55711df782a0
&image : 0x7ffc8a46dfb0
image : 0x55711df782a0
这里指针并没有变化,因为是函数调用,如果将代码中的destroy_image()
改为宏MagickFreeFunc
,则是想要的效果:
#include <stdio.h>
#include <stdlib.h>
typedef void (*MagickFreeFunc)(void *ptr);
static MagickFreeFunc FreeFunc = free;
void MagickFree(void *memory) {
if (memory != (void *)NULL)
(FreeFunc)(memory);
}
#define MagickFreeMemory(memory) \
{ \
printf("&memory: %p\n", &memory); \
printf(" memory: %p\n", memory); \
void *_magick_mp = memory; \
MagickFree(_magick_mp); \
memory = 0; \
}
void destroy_image(char *image) { MagickFreeMemory(image); }
int main() {
char *image = (char *)malloc(1024);
printf("&image : %p\n", &image);
printf(" image : %p\n", image);
MagickFreeMemory(image);
printf("&image : %p\n", &image);
printf(" image : %p\n", image);
return 0;
}
% ./a.out
&image : 0x7ffd7247ae08
image : 0x5572b59cf2a0
&memory: 0x7ffd7247ae08
memory: 0x5572b59cf2a0
&image : 0x7ffd7247ae08
image : (nil)
所以要想解决这个core dumped
的问题,就老老实实地按照GraphicsMagick
的代码风格,调用完DestroyImage()
后再紧接着赋一次0
,见commit
:fix core dumped。