[Drawkit] get tool controller?

Graham Cox graham.cox at bigpond.com
Tue Feb 17 16:19:22 PST 2009


On 18 Feb 2009, at 10:35 am, James Maxwell wrote:

> I do have another question, though... I have a class which  
> initializes just fine, and seems fine, but when I try to use one of  
> its methods, I find that one of its instance variables contains a  
> completely foreign object - and this changes arbitrarily! I'm  
> guessing there's something somewhere that's been freed, leaving my  
> instance variable is pointing to some garbage space, but I've no  
> idea how to track down the problem.
> Any tips? I haven't had this problem, so far...


It does sound like something freed that shouldn't be. These can be  
tricky to find, but start by setting NSZombieEnabled to YES (highlight  
the executable in Xcode, do Get Info, Arguments, and add  
NSZombieEnabled to 'variables to be set in the environment'). This  
won't catch the problem directly (i.e. show you where the erroneous  
free is) but it will drop you into the debugger next time the object  
is accessed. With luck this will be soon afterwards and will help  
pinpoint the problem. Make sure you turn NSZombieEnabled off for final  
builds though, because it prevents object memory being reclaimed.

Is it a DK object? What ivar is it?

Do a search for the ivar name and check every place you access it is  
doing the right thing by the memory management rules. If you release  
it anywhere other than dealloc, you should also set it to nil if it's  
not being reassigned.

Another cause of this could be code that is overwriting the variable  
with garbage. These can be b*****s to find. Sometimes it can be due to  
code that has been compiled based on incorrect assumptions, so if you  
have any warnings such as '<foo> may not respond to <bar>, methods  
without a matching signature are assumed to return id and take ... as  
arguments' are worth paying special attention to.  General advice is  
never ignore warnings - make sure you can compile without generating  
any warnings.

Also be very careful about return types. If you have two methods with  
the same name but differently sized return types, e.g.:

- (NSPoint)	getValue;
- (int)		getValue;

If the compiler plumps for the wrong one, it will corrupt the stack at  
runtime, and you don't get a warning at compile time either. This can  
happen when you use the anonymous object type (id) with such a method.  
It's best to avoid using id if you can supply a more explicit class.  
This happens because the compiler doesn't care about return type when  
matching a method signature, and if it has nothing else to go on (like  
the object class) it simply uses the first matching method that it  
happens to find in its symbol table. It will merrily compile according  
to the found return type, assuming that the surrounding code is  
consistent with it. But the reality is that the return type matters,  
and getting it wrong can cause serious corruption. This is a GCC bug.  
Rare, but real.

Here's one situation that this cropped up for me:

NSComparisonResult  comparisonFunction( id objectA, id objectB, void*  
info )
{
     float a = [objectA getValue];
     float b = [objectB getValue];

    // compare a and b and return ordering
}

Because objectA and objectB are typed as id, the lookup for -getValue  
will use the first it finds. If there are methods with the same name  
but different return types, the compiled code can corrupt the stack  
because a and b are typed as float, and thus only the right amount of  
stack space to hold two floats is assigned. If -getValue returns a  
NSPoint say, this won't fit in the stack space allowed and will  
overflow, overwriting whatever happens to be in the way. Sometimes  
even the same sizes can cause problems, like int and float, because  
these are returned in different CPU registers.

Getting rid of id and typing the objects more explicitly will fix this.

The chances of this being your problem are low, but as this is a  
"silent killer" it's worth knowing about. It also bit me hard once,  
and took days to pin down.

--Graham











More information about the Drawkit mailing list