0

I'm trying to track down the code where my UITabBar's (subclassed as ASTabBar) frame/bounds is being set. I'm using this post to guide me so that I can set a Watchpoint in the lldb debugger.

I have implemented a method called - (void)viewWillLayoutSubviews in my UITabBarController and set a breakpoint there to add my Watchpoint.

So far I have done the following:

(lldb) po self.tabBar
<ASTabBar: 0x7fd814606fc0; baseClass = UITabBar; frame = (0 574; 375 49); autoresize = W+TM; layer = <CALayer: 0x7fd814607690>>

(lldb) break set -F '-[CALayer setBounds:]' -c '((int*)$esp)[1] == 0x7fd814607690'
Breakpoint 26: where = QuartzCore`-[CALayer setBounds:], address = 0x000000010fd4e371
Stopped due to an error evaluating condition of breakpoint 26.1: "((int*)$esp)[1] == 0x7fd814607690"
Couldn't execute expression:
Supposed to interpret, but failed: Interpreter couldn't read from memory

My problem is that at some point after this method is called, the height of my UITabBar is changed from 49.f to 44.f. I want to find what's responsible for this.

I think that the reference ((int*)$esp)[1] is wrong for my implementation. I'm not sure what the [1] is referring to in the example I've been following at the link. Obviously it's an index to an offset in memory but I'm not sure what its value should be to reference the layer's frame. My guess is that it is similar to how the debugger outputs a list of details when printing out (po in debugger) the view's properties. Ordered: ASTabBar (beginning of object in memory), baseClass, frame, autoresize, and layer BUT changing the index value to [2] for instance doesn't give me a different output nor does setting it to [0] or omitting this index completely...

Lastly, I think it's odd that my method - (void)viewWillLayoutSubviews gets called twice before the view is displayed. It is here on the second time this method is called that I notice the TabBar's height is now 44.f.

1 Answer 1

0

"self" is the first parameter passed to an ObjC method call, and you are trying to limit the breakpoint to only cases where this object is "self". So the condition you want is "first argument to function == some pointer value".

Since your addresses are clearly 64 bit addresses, presumably you are debugging a 64-bit Intel program. In the 32 bit Intel ABI, arguments are passed on the stack. $esp is the stack pointer, so the example you were following is grabbing the second int after the stack pointer. That's right for 32-bit Intel.

But for the 64-bit Intel, the first few arguments are all passed in registers. So you would need to figure out which register is used for passing the first argument. However, for architectures that pass arguments in registers, lldb makes convenience alias variables: $arg1, $arg2, etc, that point to whatever the ABI specifies for passing those arguments. So the condition:

$arg1 == 0x7fd814606fc0

should mean that the breakpoint only stops when your object is passed to setBounds. This condition will work on 64 bit Intel & 32 and 64 bit ARM programs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.