<2022-04-02 Sat>
LiberateMagickResource()
的闪退问题(一)我正在处理所有标注了TODO(ocl)
的代码,在DestroyMagickCLCacheInfoAndPixels()
函数里的代码:
// RelinquishMagickResource(MemoryResource,info->length); // TODO(ocl)
DestroyMagickCLCacheInfo(info);
// (void) RelinquishAlignedMemory(pixels); // TODO(ocl)
我这样处理之后:
// RelinquishMagickResource(MemoryResource,info->length);
LiberateMagickResource(MemoryResource,info->length);
DestroyMagickCLCacheInfo(info);
// (void) RelinquishAlignedMemory(pixels);
MagickFreeAlignedMemory(pixels);
程序闪退,打印的信息如下:
$ gm display ~/temp/1.png
gm display: abort due to signal 11 (SIGSEGV) "Segmentation Fault"...
Aborted (core dumped)
确认起因是因为使用了LiberateMagickResource(MemoryResource,info->length);
这行代码。经过调试发现在GetAuthenticOpenCLBuffer()
函数返回NULL
后程序闪退。具体代码是:
if ((cache_info->type != MemoryCache)/* || (cache_info->mapped != MagickFalse) */)
return((cl_mem) NULL);
我这样修改好像不闪退了:
if ((cache_info->type != MemoryCache) || (cache_info->type != MapCache))
return((cl_mem) NULL);
目前尚未理解LiberateMagickResource(MemoryResource,info->length);
的用意,及像上面这样修改会不会引发什么新的问题。
注:必须清除.cache/ImageMagick
里的所有文件才能出现闪退问题,即在跑opencl
的benchmark
时会出现。
<2022-04-03 Sun>
LiberateMagickResource()
的闪退问题(二)理解了一下GraphicsMagick
的AcquireMagickResource()
,LiberateMagickResource()
函数,它们实际上起到监视的作用,没有分配和释放资源的功能,包括InitializeMagickResources()
函数,初始化内存分配的上限,磁盘上限等等,可以通过比如MAGICK_LIMIT_MEMORY
,MAGICK_LIMIT_DISK
等环境变量来设置。
调试发现当在DestroyMagickCLCacheInfoAndPixels()
函数中使用LiberateMagickResource()
后:
// LiberateMagickResource()
case SummationLimit:
{
/*
Limit depends on sum of previous allocations as well as
the currently requested size.
*/
LockSemaphoreInfo(info->semaphore);
info->value-=size;
value=info->value;
UnlockSemaphoreInfo(info->semaphore);
break;
}
中的info->value-=size;
可能会变成负值,这样的话,再次调用AcquireMagickResource()
时可能返回失败,即:
// AcquireMagickResource()
case SummationLimit:
{
/*
Limit depends on sum of previous allocations as well as
the currently requested size.
*/
LockSemaphoreInfo(info->semaphore);
value=info->value+size;
if ((info->maximum != ResourceInfinity) &&
(value > (magick_uint64_t) info->maximum))
{
value=info->value;
status=MagickFail;
}
else
{
info->value=value;
}
UnlockSemaphoreInfo(info->semaphore);
break;
}
这里的if
分支,这样的话,需要找到为什么LiberateMagickResource()
会将info->value
的值搞成负数?
<2022-04-06 Wed>
LiberateMagickResource()
的闪退问题(三)info->value
的值之所以为负数,原因其实很简单,不是AcquireMagickResource()
调少了,就是LiberateMagickResource()
调多了。
最终还是解决了这个问题,又是一个低级错误,一个自己给自己挖的坑,原ImageMagick
中的代码是:
// IM's RelinquishPixelCachePixels()
#if defined(MAGICKCORE_OPENCL_SUPPORT)
if (cache_info->opencl != (MagickCLCacheInfo) NULL)
{
cache_info->opencl=RelinquishMagickCLCacheInfo(cache_info->opencl,
MagickTrue);
cache_info->pixels=(Quantum *) NULL;
break;
}
#endif
这里的break;
是关键。