Can i make an Xcode breakpoint when a certain class gets added to autorelease pool?
Asked Answered
T

1

5

I'm trying to debug some ARC code, and it'd be really helpful if i could find out when an object of a certain class is added to the autorelease pool (not when it is actually autoreleased down the track).

Is this possible, eg with a breakpoint? Or by overwriting the 'autorelease' method and putting a breakpoint in it? Any suggestions?

-- edit --

The problem is that i've got an infrequent crash occurring where a custom subclass of UIView is autoreleased on a background thread, which crashes because UIView's cannot be dealloc'd on a background thread. The trace looks like below:

0    libsystem_kernel.dylib  __pthread_kill + 8
1    libsystem_c.dylib   pthread_kill + 54
2    libsystem_c.dylib   abort + 94
3    libc++abi.dylib     abort_message + 46
4    libc++abi.dylib     default_terminate() + 24
5    libobjc.A.dylib     _objc_terminate + 146
6    libc++abi.dylib     safe_handler_caller(void (*)()) + 76
7    libc++abi.dylib     operator delete(void*)
8    libc++abi.dylib     __cxa_throw + 122
9    libobjc.A.dylib     objc_exception_throw + 94
10   CoreFoundation  +[NSException raise:format:]
11   Foundation  -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 90
12   MYAPP   MySuperclass.m line 156 -[MySuperclass dealloc]
13   MYAPP  MyClass.m line 41 -[MyClass dealloc]
14 ...   libobjc.A.dylib     _objc_rootRelease + 36
15   libobjc.A.dylib     objc_release + 38
16   libobjc.A.dylib     (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 224
17   libobjc.A.dylib     _objc_autoreleasePoolPop + 12
18   CoreFoundation  _CFAutoreleasePoolPop + 18
19   libdispatch.dylib   _dispatch_worker_thread2 + 338
20   libsystem_c.dylib   _pthread_wqthread + 294
Thymus answered 24/10, 2013 at 22:32 Comment(4)
Could you tell us more about the problem you're trying to debug? Perhaps there's a better way. Note that you can use the Allocations instrument to examine the call stack of every retain, release, and autorelease message sent to every object, and you can filter by the class of interest.Ostosis
Ok i'll add it to the questionThymus
I tried to use instruments, but the app crashes immediately when launching via instruments. The crash log says: Dyld Error Message: Symbol not found: _objc_setProperty_atomicThymus
No worries, I got instruments working on a colleagues computer.Thymus
D
7

This might not help with your problem, but I think it answers your original question:

You can add a symbolic breakpoint on [NSObject autorelease] and then set a condition to match your class. If your running on a device $r0 should hold the pointer to the receiving object. You need to do some casting to make the condition work: (BOOL)[(id)$r0 isKindOfClass:[NSArray class]] breaks whenever an NSArray is added to the autoreleasepool. Note that everything will be running very slow as the debugger has to break on every autorelease and check the condition.

Add a symbolic breakpoint

enter image description here

enter image description here

Dihydric answered 24/10, 2013 at 22:52 Comment(9)
Thanks, this looks great! Any idea what the register would be for the receiving object on the simulator?Thymus
$rdi, @Chris. Greg Parker has a table with all the architecturesVorster
I think it might be $eax actually?Thymus
I get the following error in my console: error: use of undeclared identifier '$rdi'Thymus
If i change it to $eax, i get this: Couldn't execute expression: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x5de589dc). The process has been returned to the state before expression evaluation. [no Objective-C description available] Stopped due to an error evaluating condition of breakpoint 9.4: "(BOOL)[(id)$eax isKindOfClass:[NSArray class]]" Thymus
I didn't get it to work in the simulator. Maybe the iOS Debugging Magic Tech Note helps.Dihydric
On a 32-bit x86 architecture, it's (BOOL)[((id*)$esp)[1] isKindOfClass:[NSArray class]].Ostosis
Thanks rob. And once it breaks, to get access to it in the lldb console, this works: po ((id*)$esp)[1]Thymus
FWIW, this technique does work, but it's incredibly slow. I think using the instruments trace here might be more usable: http://stackoverflow.com/a/14891837/77567Thymus

© 2022 - 2024 — McMap. All rights reserved.