15

So, at a breakpoint, I have a random object instance. I want to figure out which objects have a pointer to this object. Is there a way to see this in the debugger console? Maybe something that shows me all the objects that have a retain on the object?

Example: I have a NSViewController instance and I want to see all the other objects that hold a pointer this view controller instance. This would be helpful because it would allow me to see the view controller hierarchy that is encapsulating my instance.

Just a crazy thought I had that would really help at times.

jscs
  • 63,694
  • 13
  • 151
  • 195
Jesse Bunch
  • 6,651
  • 4
  • 36
  • 59
  • 1
    I'm not sure that's possible. Not even the runtime maintains that kind of information, because it would mean the child has knowledge of it's parent (it violates dependancy rules). – CodaFi Jun 03 '13 at 03:02
  • Maybe you're right. I was thinking more of a dumb memory search for objects that contain a pointer to 0x2827... – Jesse Bunch Jun 03 '13 at 03:22
  • A dumb memory search won't find objects, though. It'll find data but it won't know what it stands for. – StilesCrisis Jun 03 '13 at 05:03
  • possible duplicate of [Get all existing pointers to an object](http://stackoverflow.com/questions/8600922/get-all-existing-pointers-to-an-object) – jscs Jun 03 '13 at 05:10
  • It is not easy to do this using `lldb`. But you might want to check out the Allocations instrument. It can show you the stack trace of every `retain`, `release`, and `autorelease` of your objects. Take a look at [this answer](http://stackoverflow.com/a/14891837/77567) for help getting started. – rob mayoff Jun 03 '13 at 05:42
  • It is actually pretty easy to do this in lldb thanks to the python scripting capabilities built in. lldb comes packaged with the `ptr_refs` command in Xcode 4.6 (see Greg Parker's answer) for native Mac development - it (essentially) greps through your memory looking for references to the address of interest. It compiles and loads a little bundle in to your program to assist which is why it is limited to Mac native; in our top of tree development sources it uses the expression parser/jit to compile & run the necessary code in your program so it can work on iOS too. – Jason Molenda Jun 04 '13 at 02:16

2 Answers2

34

In lldb, use command script import lldb.macosx.heap to install some memory-searching functions. The ptr_refs command should be able to do what you want; use ptr_refs --help to learn more.

Greg Parker
  • 7,972
  • 2
  • 24
  • 21
  • 2
    `ptr_refs` is the way to go. If you launch your app with the `MallocStackLogging=1` environment variable, you can do `ptr_refs --stack ADDRESS` and not only see all memory blocks that contain that address but the backtrace when that object / memory block was allocated or freed. Note that `ptr_refs` is only for Mac OS X apps at this point - the way it is implemented in Xcode 4.6 precludes it from working on iOS. – Jason Molenda Jun 03 '13 at 23:11
  • 2
    With Xcode 6.3 I successfully used `ptr_refs` on an iOS app running both on a device (iOS 7.1.2) and in the simulator (iOS 8.3), so it looks like it's not limited to Mac OS X any more. – user2067021 Apr 15 '15 at 23:06
  • @user2067021, And what did you import for it to work? `lldb.ios.heap` doesn't seem to exist – Iulian Onofrei Jun 16 '16 at 08:24
  • @lulianOnofrei Tried it again just now with Xcode 7.3.1 (using `lldb.macosx.heap`) on an iOS device (9.3.2) and it's pretty flakey. It crashes Xcode in most stack frames I tried, although occasionally I get a sensible result. It doesn't look reliable now. – user2067021 Jun 17 '16 at 03:18
  • I heard there were compatibility issues earlier on, but I've been trying it for iOS apps with `command script import lldb.macosx.heap` recently and it is working pretty well. https://stackoverflow.com/questions/62310636/how-do-i-read-references-given-by-ptr-refs-in-ios/62490505#62490505 has a detailed example of how to use it to find the line in your source code that is pointing to a particular object. – auspicious99 Jun 21 '20 at 08:01
0

Not an efficient solution, or applicable in all cases, but you could encapsulate the object you're looking for in an accessor method on one of your classes, and put a breakpoint inside. By stepping through the end of the accessor method, you can eventually see all the call points.

Alternatively, you can remove the definition of the variable, and the compiler will spit out a ton of errors, each will also be a call to this object.

I'd suggest using ARC if you're not already. Ideally your code wouldn't be messy enough that you wouldn't be able to identify references by reading through the code, ARC can help a little bit in that department

Jeremy Massel
  • 2,257
  • 18
  • 22