discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Infinite loop in objc_storeWeak


From: David Chisnall
Subject: Re: Infinite loop in objc_storeWeak
Date: Mon, 18 Jun 2012 11:51:17 +0100

This code works as expected.  It appears that you are misunderstanding how weak 
variables work in Objective-C.

When you read from a __weak pointer, you get an autoreleased pointer.  This 
guarantees that the weak pointer is not deallocated at the wrong time.  For 
example, in your example you do:

[r target];

This loads the __weak ivar _target, retains and autoreleases it, and then 
returns it.

When called in ARC mode, the compiler inserts a call to 
objc_retainAutoreleasedReturnValue(), which pops the object off the autorelease 
pool and retains it.  This is then followed by a call to objc_release(), which 
decrements the reference count so that there are now no strong pointers to the 
weak object, and once you do o = nil; (which becomes a call to 
objc_storeStrong(), or possibly objc_release() followed by an assignment )it 
can be deallocated.  

In ARC mode, the compiler can be a lot more aggressive about removing things 
from the autorelease pool, which is one of the main reasons that it leads to 
increased performance: objects don't hang around in autorelease pools for as 
long a time burning data cache.  

Short version: never release a __weak pointer.  Bad things will happen.  As I 
said, the most likely cause for the error that you saw is some incorrect memory 
management in your code.

David

On 18 Jun 2012, at 10:43, Thomas Davie wrote:

> On 15 Jun 2012, at 14:50, David Chisnall wrote:
> 
>> Can you try to produce a reduced test case?  I've tried a few things and I 
>> can't make it not work.  For example, this code:
>> 
>> int main(void)
>> {
>>   BBWeakRef *o = [BBWeakRef refWithTarget: [NSObject new]];
>>   NSLog(@"%@", o.target);
>> }
>> 
>> Logs (null) as expected.  A backtrace might help.  As would compiling 
>> libobjc2 without optimisations (you can't actually be infinite looping in a 
>> loop that counts from 0 to 3, you must be looping in the outer loop for some 
>> reason).  The most likely cause of this is that you're trying to create a 
>> weak reference to an object that's already been deallocated.  Perhaps you 
>> could try GSZombieEnabled=YES as well?
> 
> Hi David,
> 
> Sorry for the delayed response, I wanted to make sure I had something 100% 
> reproducible.  Unfortunately, I wasn't able to reproduce the exact bug – it 
> appears to be something deeply embedded in my code, but I have been able to 
> reproduce something I believe is strongly related:
> 
> Description:
> Weak references are not zeroed when ARC code is linked with non-ARC code.
> 
> Steps to Reproduce
> 1) Unzip the attached source folders.  You should find:
> BBWeakRef – a directory containing a simple weak reference wrapper, set to 
> compile using ARC
> WeakRefTest – a directory containing a simple test program that links against 
> BBWeakRef, but is not compiled using ARC
> WeakRefTest2 – a directory containing a similar test program that uses ARC, 
> and includes BBWeakRef's source.
> 2) make & make install BBWeakRef
> 3) make WeakRefTest and run it.
> 4) make WeakRefTest2 and run it.
> 
> Expected Results:
> From WeakRefTest:
> 2012-06-18 10:32:47.445 test[18025] 0xdeadbeef - <NSObject: 0xdeadbeef >
> 2012-06-18 10:32:47.448 test[18025] (null) - (null)
> 2012-06-18 10:32:47.448 test[18025] (null) - (null)
> 
> From WeakRefTest2:
> 2012-06-18 10:36:28.615 test[18117] 0x11012c8 - <NSObject: 0x11012c8>
> 2012-06-18 10:36:28.618 test[18117] (null) - (null)
> 
> 
> Actual Results:
> From WeakRefTest:
> 2012-06-18 10:32:47.445 test[18025] 0x11f82c8 - <NSObject: 0x11f82c8>
> 2012-06-18 10:32:47.448 test[18025] 0x11f82c8 - <NSObject: 0x11f82c8>
> 2012-06-18 10:32:47.448 test[18025] 0x11f82c8 - <NSObject: 0x11f82c8>
> Segmentation fault
> 
> Thanks
> 
> Tom Davie
> 
> <Archive.zip>


-- Sent from my Apple II




reply via email to

[Prev in Thread] Current Thread [Next in Thread]