<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。

文章探讨了一个在GraphicsMagick中因低级错误导致coredumped的问题,涉及内存管理中的函数调用和宏使用,指出在DestroyImage后必须再次将pointer置0以确保正确释放资源。
2540

被折叠的 条评论
为什么被折叠?



