Tips for debugging EXC_BAD_ACCESS

Michel Fortin michel.fortin at michelf.ca
Fri Oct 12 07:57:53 PDT 2012


On 2012-10-12 12:40:35 +0000, Jacob Carlborg <doob at me.com> said:

> On 2012-10-11 20:19, Michel Fortin wrote:
> 
>> Most likely, the object objc_msgSend is called on has been deallocated,
>> which would mean that windowSendEvent is called with a deallocated
>> NSWindow object as its first argument.
> 
> I have done some investigation and I can call other methods on the 
> NSWindow object, but regular methods and super methods. This would 
> indicate that it's something wrong with the NSEvent object, but I can 
> call methods on that as well.

That's not a very good proof. You might just be calling a method on the 
object before it gets released. Often, Objective-C objects are 
autoreleased, which means that deallocation is postponed until the end 
of the current event loop iteration (unless someone increase the 
reference counter again), so you might be having a valid pointer to it 
right now, but it might already be in the queue for deallocation.

If you want to test for the deallocated object theory, just call retain 
via objc_msgSend on any object you suspect might be deallocated too 
early, one by one, until you find the one that is causing the trouble. 
Once you find the problematic object, print its address on the console 
and use Instrument…


>> Since you're on OS X, I'd suggest you try using Instruments to track the
>> reference counters of all Objective-C objects within your program until
>> it crashes, then search back the history for all
>> retain/release/autorelease calls made to the address the EXEC_BAD_ACCESS
>> happens on.
> 
> I don't know how to use Instruments for this.

It's the Allocations profile you need. It'll record logs of every 
allocation, deallocation, and optionally every change to reference 
counters (click the (i) icon next to Allocations and check "Record 
reference counts"). Each log entry has a stack trace.

To see the raw log, you should open the Object List pane at the bottom 
(click the Statistics button, it's a menu). There'll be a lot of 
unrelated allocations, which is why you should output the pointer 
address to the object to the console (available under the same menu), 
and then search it in the log (or filter on it). Then look at the call 
stack for each entry, and hopefully you'll understand what's happening.

I hope this helps.


-- 
Michel Fortin
michel.fortin at michelf.ca
http://michelf.ca/



More information about the Digitalmars-d mailing list