How to Read References Given by Ptr_Refs in iOS

How do i read references given by ptr_refs in iOS?

Firstly, the names on the right give us some clues, from which you could guess that TtC13ThreadChecker14ViewController is associated with your ViewController class.

_Tt is for target; C is for class; 13 is the length of the "ThreadChecker" string, and your project name is ThreadChecker; 14 is the length of the "ViewController" string, and that is the class. Your ViewController starts at 0x10290bd20.

Secondly, the malloc is at 0x000000010290c070. Notice that 0x000000010290c070 - 0x10290bd20 = 0x350 which is 848 in decimal, so that's why it puts the offset as 848 from the start of "ViewController", i.e., 0x10290bd20 + 848. So this offset, 848, is an important piece of the puzzle.

Thirdly, the next thing to do is figure out what line in the source code is at offset 848. For this, we begin by doing

(lldb) image list
[ 0] 4EB96CD6-42E0-34D8-AB5B-2418F5C55678 0x000000010252c000 /Users/daniel.wong/Library/Developer/Xcode/DerivedData/testLLDB-eqmuowhdphumqdhcyvcydgrybiue/Build/Products/Debug-iphonesimulator/testLLDB.app/testLLDB

Even in this simple example, there might be 200-300 libraries loaded with the app. For the present investigation of your own source code, you can ignore the libraries, only look at the [ 0] (first element in the list).
(in my example, the app is called testLLDB; in yours, you might see ThreadChecker instead of testLLDB).

An important point to note is that image list gives the so-called file address where the addresses you got from Xcode that you used for ptr_refs might be quite different (actual addresses in the simulator or iPhone memory during an actual run when it gets loaded into a part of the RAM), e.g., 0x102914810 in your example. The file address refers to a virtual address as defined by each object file. For the purpose of finding the source code line number with the offset 848, you can work with these file addresses and you now just need one more piece of information, i.e., where is the start of the code for ViewController, so you can take offset 848 from there.

Fourthly, to find the start of the code for ViewController, you can use

(lldb) image dump sections  /Users/daniel.wong/Library/Developer/Xcode/DerivedData/testLLDB-eqmuowhdphumqdhcyvcydgrybiue/Build/Products/Debug-iphonesimulator/testLLDB.app/testLLDB

where we specified only the image of the testLLDB app that we got as the first element of the image list, and not the 100s of libraries after that.

lldb will then give you something like:

Sections for '/Users/daniel.wong/Library/Developer/Xcode/DerivedData/testLLDB-eqmuowhdphumqdhcyvcydgrybiue/Build/Products/Debug-iphonesimulator/testLLDB.app/testLLDB' (x86_64):
SectID Type Load Address Perm File Off. File Size Flags Section Name
---------- ---------------- --------------------------------------- ---- ---------- ---------- ---------- ----------------------------
0x00000100 container [0x0000000000000000-0x0000000100000000)* --- 0x00000000 0x00000000 0x00000000 testLLDB.__PAGEZERO
0x00000200 container [0x000000010252c000-0x0000000102532000) r-x 0x00000000 0x00006000 0x00000000 testLLDB.__TEXT
0x00000001 code [0x000000010252d260-0x000000010252fa80) r-x 0x00001260 0x00002820 0x80000400 testLLDB.__TEXT.__text
0x00000002 code [0x000000010252fa80-0x000000010252fb5e) r-x 0x00003a80 0x000000de 0x80000408 testLLDB.__TEXT.__stubs
0x00000003 code [0x000000010252fb60-0x000000010252fce2) r-x 0x00003b60 0x00000182 0x80000400 testLLDB.__TEXT.__stub_helper
0x00000004 data-cstr [0x000000010252fce2-0x00000001025309bf) r-x 0x00003ce2 0x00000cdd 0x00000002 testLLDB.__TEXT.__objc_methname
0x00000005 data-cstr [0x00000001025309c0-0x0000000102531817) r-x 0x000049c0 0x00000e57 0x00000002 testLLDB.__TEXT.__cstring
0x00000006 regular [0x0000000102531820-0x0000000102531b50) r-x 0x00005820 0x00000330 0x00000000 testLLDB.__TEXT.__const
...

There's more, but for this simple ViewController, these first few sections are enough for our purpose. Look at the first code section, where its range is [0x000000010252d260-0x000000010252fa80). So it is starting from 0x000000010252d260. Here is where we add the offset 848. But we add in hex, so we add 0x350 to 0x000000010252d260 to get 0x000000010252d5b0.

Fifthly and finally, we can see which part of our source code was referencing the label, by:

(lldb) image lookup -a 0x000000010252d5b0 --verbose
Address: testLLDB[0x00000001000015b0] (testLLDB.__TEXT.__text + 848)
Summary: testLLDB`key path getter for testLLDB.ViewController.label : Swift.Optional<__C.UILabel> : testLLDB.ViewController + 80 at <compiler-generated>
Module: file = "/Users/daniel.wong/Library/Developer/Xcode/DerivedData/testLLDB-eqmuowhdphumqdhcyvcydgrybiue/Build/Products/Debug-iphonesimulator/testLLDB.app/testLLDB", arch = "x86_64"
CompileUnit: id = {0x00000000}, file = "/Users/daniel.wong/OneDrive - V-Key Pte Ltd/ios/testLLDB/testLLDB/testLLDB/ViewController.swift", language = "swift"
Function: id = {0x10000032e}, name = "key path getter for testLLDB.ViewController.label : Swift.Optional<__C.UILabel> : testLLDB.ViewController", mangled = "$s8testLLDB14ViewControllerC5labelSo7UILabelCSgvpACTK", range = [0x000000010252d560-0x000000010252d5bf)
FuncType: id = {0x10000032e}, byte-size = 8, compiler_type = "() -> ()
"
Blocks: id = {0x10000032e}, range = [0x10252d560-0x10252d5bf)
LineEntry: [0x000000010252d560-0x000000010252d5c0): /Users/daniel.wong/OneDrive - V-Key Pte Ltd/ios/testLLDB/testLLDB/<compiler-generated>
Symbol: id = {0x000000a4}, range = [0x000000010252d560-0x000000010252d5c0), name="key path getter for testLLDB.ViewController.label : Swift.Optional<__C.UILabel> : testLLDB.ViewController", mangled="$s8testLLDB14ViewControllerC5labelSo7UILabelCSgvpACTK"
Variable: id = {0x100000345}, name = "label", type = "testLLDB.ViewController", location = DW_OP_fbreg(-16), decl = ViewController.swift:18

So we see it is "key path getter for testLLDB.ViewController.label : Swift.Optional<__C.UILabel> : testLLDB.ViewController" at ViewController.swift:18, which is what you were looking for. (ok, for my test view controller, the label is in line 18, as I also had a viewDidLoad that took a few lines; for yours, you should get the appropriate line number for your ViewController).

This post is already too long, but just to add one more little piece of info: those references to your label from CFXNotificationObjcObserverRegistration, that is part of CoreFoundation, so we see that not at references are from our own source code. Many references would often be from system frameworks like CoreFoundation, etc.; if you put your view with the label in a storyboard and add auto layout constraints, for example, the ptr_refs command will additionally give you a number of other references that are related to auto layout, e.g.,

NSContentSizeLayoutConstraint.NSLayoutConstraint._container
0x000060000049ce48: malloc( 96) -> 0x60000049ce40 + 8 NSContentSizeLayoutConstraint.NSLayoutConstraint._container
0x00006000035db208: malloc( 64) -> 0x6000035db200 + 8 NSLayoutDimension.NSLayoutAnchor._referenceItem
0x00006000035db3c8: malloc( 64) -> 0x6000035db3c0 + 8 NSLayoutDimension.NSLayoutAnchor._referenceItem
0x00006000035e9560: malloc( 64) -> 0x6000035e9540 + 32

LLDB: Show all objects with a pointer to an object in memory

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.

How to debug message sent to deallocated instance in Xcode 4?

If this crops up again, you can run a dedicated Zombies instrument. Hit Command+I to profile the app and select the Zombies instrument (you must be running on the simulator). If you get a zombie, you can display the entire memory history (each retain/release) for that object, which is immensely helpful in tracking down errors.

How can I fix STATUS_ACCESS_VIOLATION by VecT allocation?

Right, so I think there are a couple of different issues to unpack here.

First you need to understand what a Vec is. A Vec is not like a C-style array, but rather more like a C++ std::vector. The Vec object itself just contains two items (often called the "control block"): a wide pointer to the heap-allocated space for the elements of the Vec (including the allocated capacity), and the current length of the Vec. The actual elements of the Vec exist elsewhere, in memory allocated by the Vec itself and pointed to by that wide pointer it holds in the control block.

So, in you code ptr points to a region of heap memory allocated with enough space to hold a Vec object, that is to hold the control block. You never actually initialise a Vec object, just allocate enough memory to hold one.

Then you do your first "bad thing", you cast ptr to a &mut Vec. But you never initialised a Vec object there (i.e., the allocated memory for the control block has not been initialised). References in Rust cannot point to uninitialised memory, doing violates safety and your whole program is invalid. In particular, you call the resize_with method on a "Vec", but there is no Vec there, just some block of heap memory with the size and alignment to theoretically hold a Vec's control block.

What I suppose you think you're doing is that the pointer to Vec doesn't point at the control block, but directly to the heap memory containing the elements of the Vec. This would make some sense of why you try to dealloc the way that you do, with a pointer to the first element of the Vec rather than the Vec itself. That is also wrong, since that isn't pointing at the memory you alloc'd.


So what should you be doing? I'm not an expert because I've never felt the need to manually de/allocate in Rust before, but my understanding is that you can simply do *ptr = Vec::new() (or whatever Vec constructor you want) and then you can cast back to a &mut Vec since there's now an initialised Vec there.

Then, when you're done you fist need to make sure that the Vec gets dropped -- this will cause it to internally deallocate the space allocated for the elements -- before you do dealloc(ptr.cast(), layout).



Related Topics



Leave a reply



Submit