URL:
<http://savannah.gnu.org/bugs/?33392>
Summary: Multi-thread bug in NSObject retain and release
Project: GNUstep
Submitted by: jpolsonaz
Submitted on: Tue 24 May 2011 04:14:12 PM GMT
Category: Base/Foundation
Severity: 3 - Normal
Item Group: Bug
Status: None
Privacy: Public
Assigned to: None
Open/Closed: Open
Discussion Lock: Any
_______________________________________________________
Details:
I have experienced frequent crashes in a heavily multi-threaded GNUstep
application. All of these crashes indicate memory corruption, double frees,
etc. I traced these crashes to the following atomic increment code in
NSObject.m which is NOT atomic at all.
static __inline__ int
GSAtomicIncrement(gsatomic_t X)
{
__asm__ __volatile__ (
"lock addl $1, %0"
:"=m" (*X));
return *X;
}
static __inline__ int
GSAtomicDecrement(gsatomic_t X)
{
__asm__ __volatile__ (
"lock subl $1, %0"
:"=m" (*X));
return *X;
}
Note that although the locked addl/subl instructions are atomic, the following
return *X results in a separate mov instruction. If a context switch occurs
between these instructions, these functions can return incorrect values.
Later, NSObject uses the returned result from GSAtomicDecrement to determine
if the object must be deallocated.
result =
GSAtomicDecrement((gsatomic_t)&(((obj)anObject)[-1].retained));
if (result < 0)
{ /// deallocate object
If two threads simultaneously release the same object, it's possible for both
threads to invoke dealloc.
To work around this issue, I rebuilt GNUstep to use the slower NSLock rather
than the atomic increment/decrement instructions which eliminated these
crashes.
_______________________________________________________
Reply to this item at:
<http://savannah.gnu.org/bugs/?33392>
_______________________________________________
Message sent via/by Savannah
http://savannah.gnu.org/
_______________________________________________
Bug-gnustep mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-gnustep