Deadlock in ReadOnePNGImage

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
bytep

Deadlock in ReadOnePNGImage

Post by bytep »

Here is the version of the ImageMagick used:

> identify -version
Version: ImageMagick 6.5.3-1 2009-11-23 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2009 ImageMagick Studio LLC

Magick++ is used in a multi-threaded C application on Solaris 10. Magick++ seems to get into a deadlock situation in ReadOnePNGImage.
pstack of the process shows around 8 threads in that state. Here are some of the callstacks:

----------------- lwp# 11 / thread# 11 --------------------
fffffd7ffcd27177 lwp_park (0, 0, 0)
fffffd7ffcd1fb88 mutex_lock_impl () + e8
fffffd7ffcd1fc7b mutex_lock () + b
fffffd7ffd629099 LockSemaphoreInfo () + 69
fffffd7ffd759434 ReadOnePNGImage () + 94
fffffd7ffd75c549 ReadPNGImage () + 1d9
fffffd7ffd4b02ce ReadImage () + 31e
fffffd7ffd46c708 BlobToImage () + 228
fffffd7ffd9b4e0f __1cGMagickFImageEread6Mrkn0AEBlob__v_ () + 4f
fffffd7ffefe2cf2 __1cOImageOptimizerIoptimize6MpviiiiipcipF1pCLpL_LpF1pkCL_L_i_ () + 142
fffffd7ffe74824d bmi_doFinal () + 4d
fffffd7ffeae376a opt_final_func () + 92
fffffd7ffeb2b8c6 worker_thread_fsm () + 3ae
fffffd7ffcd26ecb _thr_setup () + 5b
fffffd7ffcd27100 _lwp_start ()
----------------- lwp# 12 / thread# 12 --------------------
fffffd7ffcd27177 lwp_park (0, 0, 0)
fffffd7ffcd1fb88 mutex_lock_impl () + e8
fffffd7ffcd1fc7b mutex_lock () + b
fffffd7ffd629099 LockSemaphoreInfo () + 69
fffffd7ffd759434 ReadOnePNGImage () + 94
fffffd7ffd75c549 ReadPNGImage () + 1d9
fffffd7ffd4b02ce ReadImage () + 31e
fffffd7ffd46c708 BlobToImage () + 228
fffffd7ffd9b4e0f __1cGMagickFImageEread6Mrkn0AEBlob__v_ () + 4f
fffffd7ffefe2cf2 __1cOImageOptimizerIoptimize6MpviiiiipcipF1pCLpL_LpF1pkCL_L_i_ () + 142
fffffd7ffe74824d bmi_doFinal () + 4d
fffffd7ffeae376a opt_final_func () + 92
fffffd7ffeb2b8c6 worker_thread_fsm () + 3ae
fffffd7ffcd26ecb _thr_setup () + 5b
fffffd7ffcd27100 _lwp_start ()
----------------- lwp# 13 / thread# 13 --------------------
fffffd7ffcd27177 lwp_park (0, 0, 0)
fffffd7ffcd1fb88 mutex_lock_impl () + e8
fffffd7ffcd1fc7b mutex_lock () + b
fffffd7ffd629099 LockSemaphoreInfo () + 69
fffffd7ffd759434 ReadOnePNGImage () + 94
fffffd7ffd75c549 ReadPNGImage () + 1d9
fffffd7ffd4b02ce ReadImage () + 31e
fffffd7ffd46c708 BlobToImage () + 228
fffffd7ffd9b4e0f __1cGMagickFImageEread6Mrkn0AEBlob__v_ () + 4f
fffffd7ffefe2cf2 __1cOImageOptimizerIoptimize6MpviiiiipcipF1pCLpL_LpF1pkCL_L_i_ () + 142
fffffd7ffe74824d bmi_doFinal () + 4d
fffffd7ffeae376a opt_final_func () + 92
fffffd7ffeb2b8c6 worker_thread_fsm () + 3ae
fffffd7ffcd26ecb _thr_setup () + 5b
fffffd7ffcd27100 _lwp_start ()

.....


Unfortunately, I don't have the images that caused this problem.
Have you ever seen this problem? From the stacks, do you have insights of what could cause this problem?
Your help is highly appreciated.

Here is how Magick++ is used:
...

Code: Select all

try
   {
      Blob blob(buf, image_size);
      Blob output_blob;
  
      Image image;
      image.read(blob);

      if (outputFormat != NULL)
      {
         image.magick(outputFormat);
      }

      if (xSize != 0)
      {
         Geometry newDims(xSize, ySize);
         if (ignoreAspectRatio)
         {
            newDims.aspect(true);
         }

         image.resize(newDims);
      }

      image.write(&output_blob);

      output_buf =  output_blob.data();
      output_length = output_blob.length();
...
   }
catch { ...}
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Deadlock in ReadOnePNGImage

Post by magick »

Two paths forward: 1) Upgrade to ImageMagick 6.6.3-7 and see if the dead lock persists; or 2) post a complete Magick++ source module that we can download and use to reproduce the problem.
carbon0404
Posts: 17
Joined: 2012-04-11T05:11:30-07:00
Authentication code: 8675308

Re: Deadlock in ReadOnePNGImage

Post by carbon0404 »

Well,I have encoutered likely problem when using ImageMagick-6.7.6-2.tar.gz,I used Magick++ API in my multithreaded C++ application.and after less than 10,000 pics are transformed,it's deadlocked.and gstack like this:
Thread 50 (Thread 0x7f2ac5b86710 (LWP 15433)):
#0 0x00007f2acde9c0a4 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007f2acde97429 in _L_lock_1004 () from /lib64/libpthread.so.0
#2 0x00007f2acde9723e in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007f2acd265da6 in LockSemaphoreInfo () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#4 0x00007f2acd32d8f2 in WriteOnePNGImage () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#5 0x00007f2acd336ad7 in WritePNGImage () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#6 0x00007f2acd18bcff in WriteImage () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#7 0x00007f2acd15b5c2 in ImageToBlob () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#8 0x00007f2acd9db746 in Magick::Image::write(Magick::Blob*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long) () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagick++.so.5
#9 0x0000000000557a7b in nsImageConvert::CImageConvertMagick::convert(nsImageConvert::IImageConvert::SInfo, std::vector<char, std::allocator<char> >&) ()
#10 0x0000000000473ea6 in BaseImageConvert::doConvert(char const*, unsigned long, MTT::ImageSize&, MTT::ImageSize&, std::vector<char, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, MTT::ImageConvertReq const&, nsImageConvert::CImageConvertRuler&, ImageConvert_Normal_Tag) ()
#11 0x000000000048639a in BaseImageConvert::doConvert(char const*, unsigned long, MTT::ImageSize&, MTT::ImageSize&, std::vector<MTT::ImageData, std::allocator<MTT::ImageData> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, MTT::ImageConvertReq const&, nsImageConvert::CImageConvertRuler&, int, bool, int) ()
#12 0x000000000048cf3e in BaseImageConvert::convert(nsImageConvert::CImageConvertRuler&, int, MTT::CookieCacheClient&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, MTT::ImageConvertReq const&, MTT::ImageSize const&, int, MTT::CrawlerRspInfo const&, bool, int) ()
#13 0x0000000000549173 in CrawlerCallback::callback_load(int, MTT::CrawlerRspInfo const&) ()
#14 0x00000000005cff19 in CrawlerSmartClientCallback::callback_loadImage(int, MTT::CrawlerRspInfo const&) ()
#15 0x00000000005e0564 in MTT::CrawlerPrxCallback::onDispatch(taf::TC_AutoPtr<taf::ReqMessage>) ()
#16 0x0000000000910f69 in taf::AsyncProcThreadRunner::run() ()
#17 0x000000000080a944 in taf::TC_Thread::threadEntry(taf::TC_Thread*) ()
#18 0x00007f2acde955f0 in start_thread () from /lib64/libpthread.so.0
#19 0x00007f2acbe2287d in clone () from /lib64/libc.so.6
#20 0x0000000000000000 in ?? ()
Thread 49 (Thread 0x7f2ac5385710 (LWP 15434)):
#0 0x00007f2acde9c0a4 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007f2acde97429 in _L_lock_1004 () from /lib64/libpthread.so.0
#2 0x00007f2acde9723e in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007f2acd265da6 in LockSemaphoreInfo () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#4 0x00007f2acd33bcd9 in ReadOnePNGImage () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#5 0x00007f2acd33f69d in ReadPNGImage () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#6 0x00007f2acd18ca3e in ReadImage () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#7 0x00007f2acd15c43f in BlobToImage () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagickCore.so.5
#8 0x00007f2acd9dc7d5 in Magick::Image::read(Magick::Blob const&) () from /usr/local/app/taf/tafnode/data/lib/ImageMagick/lib/libMagick++.so.5
#9 0x0000000000559d0d in nsImageConvert::CImageConvertMagick::init(char const*, int, bool) ()
#10 0x000000000046f813 in BaseImageConvert::doConvert(char const*, unsigned long, MTT::ImageSize&, MTT::ImageSize&, std::vector<char, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, MTT::ImageConvertReq const&, nsImageConvert::CImageConvertRuler&, ImageConvert_Normal_Tag) ()
#11 0x000000000048639a in BaseImageConvert::doConvert(char const*, unsigned long, MTT::ImageSize&, MTT::ImageSize&, std::vector<MTT::ImageData, std::allocator<MTT::ImageData> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, MTT::ImageConvertReq const&, nsImageConvert::CImageConvertRuler&, int, bool, int) ()
#12 0x000000000048cf3e in BaseImageConvert::convert(nsImageConvert::CImageConvertRuler&, int, MTT::CookieCacheClient&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, MTT::ImageConvertReq const&, MTT::ImageSize const&, int, MTT::CrawlerRspInfo const&, bool, int) ()
#13 0x0000000000549173 in CrawlerCallback::callback_load(int, MTT::CrawlerRspInfo const&) ()
#14 0x00000000005cff19 in CrawlerSmartClientCallback::callback_loadImage(int, MTT::CrawlerRspInfo const&) ()
#15 0x00000000005e0564 in MTT::CrawlerPrxCallback::onDispatch(taf::TC_AutoPtr<taf::ReqMessage>) ()
#16 0x0000000000910f69 in taf::AsyncProcThreadRunner::run() ()
#17 0x000000000080a944 in taf::TC_Thread::threadEntry(taf::TC_Thread*) ()
#18 0x00007f2acde955f0 in start_thread () from /lib64/libpthread.so.0
#19 0x00007f2acbe2287d in clone () from /lib64/libc.so.6
#20 0x0000000000000000 in ?? ()

how can I solve this problem??????
User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: Deadlock in ReadOnePNGImage

Post by glennrp »

I've attempted to fix this in IM-6.7.6-6 (SVN r 7452) by changing all Magick*Exception() calls to png_error() calls in those parts of the PNG codec that follow a setjmp() call, to ensure that every return from the codec cleans up properly, including unlocking the semaphore. This is a substantial patch, so let us know if it works for you. Besides fixing the problem you reported, it may also stop some memory leaks.
carbon0404
Posts: 17
Joined: 2012-04-11T05:11:30-07:00
Authentication code: 8675308

Re: Deadlock in ReadOnePNGImage

Post by carbon0404 »

glennrp,first,thank you very much for your fast response.and I seem to have solved this problem by configure options.thus is the description of the process:
when it's zombie,I attach the process id into gdb,and found that all the threads hunged on libgomp.so;so I add the --disable-openmp configure option.reconfigure,rebuild and reinstall,after that,it runs well.
The end configure command is :/configure CXXFLAGS="-I$CWD/ImageMagick/include " CFLAGS="-I$CWD/ImageMagick/include " LDFLAGS="-L$CWD/ImageMagick/lib " --prefix=/usr/local/mqq/ImageMagick --with-gnu-ld=yes --with-perl=no --with-x=no --without-xml --without-wmf --with-exif=no --enable-lzw=yes --disable-openmp
it seems a little strange that --disable-openmp can not work with '=yes' postfix

I still use the 6.7.6-2 vesion,and I will keep an eye on the memory leak situation.If it's still serious,I will consider update it again.For some reason,update is not so frequent.
thank you again!
Post Reply