Race condition in exception handling
Posted: 2009-03-19T05:08:18-07:00
I've seen a lot of failed asserts in a multithreaded environment like this one:
My opinion is that the locking of the ExceptionInfo during the InheritException call is insufficient:
It only locks the semaphore for the destination ExceptionInfo, but does nothing to prevent that the source ExceptionInfo is deleted during the run.
But since the invalid ExceptionInfo is a member of the source image struct, the problem could as well be that the source image is deleted during the "despeckle" run.
Also possible: the function invoked just before the despeckle (Zoom or Scale) somehow destroyed the image, and the next CloneImage call is not guilty at all, it just happens to notice it first.
In the backtrace above, the souce image object is only used inside one thread, and can't be concurrently accessed by a different one.
Unfortunatly, I couldn't reproduce this crash with a small test programm only executing the despeckle-method, so I don't have more detailed information. Except maybe that at the moment of the crash two other threads were also inside "Despeckle", but were working on different Images.
- assertion=0xf797f128 "list_info != (LinkedListInfo *) ((void *)0)",
file=0xf797f115 "magick/hashmap.c", line=1972,
function=0xf797f1f8 "ResetLinkedListIterator"
Code: Select all
#1 0xf78d3e86 in ResetLinkedListIterator (list_info=0x0)
at magick/hashmap.c:1972
#2 0xf78bf85c in InheritException (exception=0xd84fff04, relative=0xb17144c)
at magick/exception.c:599
#3 0xf78db082 in CloneImage (image=0xb16e290, columns=122, rows=152,
orphan=MagickTrue, exception=0xe3efd670) at magick/image.c:1100
#4 0xf78a9f0a in DespeckleImage (image=0xb16e290, exception=0xe3efd670)
at magick/effect.c:1429
#5 0xf7ad2fc0 in Magick::Image::despeckle () from /usr/lib/libMagick++.so.2
It only locks the semaphore for the destination ExceptionInfo, but does nothing to prevent that the source ExceptionInfo is deleted during the run.
But since the invalid ExceptionInfo is a member of the source image struct, the problem could as well be that the source image is deleted during the "despeckle" run.
Also possible: the function invoked just before the despeckle (Zoom or Scale) somehow destroyed the image, and the next CloneImage call is not guilty at all, it just happens to notice it first.
In the backtrace above, the souce image object is only used inside one thread, and can't be concurrently accessed by a different one.
Unfortunatly, I couldn't reproduce this crash with a small test programm only executing the despeckle-method, so I don't have more detailed information. Except maybe that at the moment of the crash two other threads were also inside "Despeckle", but were working on different Images.