How do I set an lldb watchpoint on a property of self.view?

前端 未结 2 2117
一向
一向 2020-12-12 17:26

I want to trace when something changes the size of self.view. What\'s the correct format?

(lldb) po self.view
(UIView *) $1 = 0x0a8aba20 

        
相关标签:
2条回答
  • 2020-12-12 18:22

    The view controller references its view from its _view instance variable.

    The view doesn't store its frame directly. It just returns its layer's `frame'.

    The view references its layer from its _layer instance variable.

    The layer doesn't store the frame either. It computes its frame from its bounds, position, anchorPoint, and transform. The size is part of bounds.

    The layer doesn't store its bounds directly in an instance variable. Instead, its layer instance variable references an instance of a private C++ class, CA::Layer. The member layout of this class is undocumented.

    In other words, you can go self->_view->_layer->layer to get to the CA::Layer instance, but then you're stuck because you don't know where in the CA::Layer to find the bounds.

    So, trying to use a watchpoint to detect changes to the view's size is rather difficult.

    It is easier to put a breakpoint on -[CALayer setBounds:].

    On the simulator

    Remember to use the layer address in the breakpoint condition, not the view address.

    (lldb) po self.view
    (UIView *) $1 = 0x0a034690 <UIView: 0xa034690; frame = (0 20; 768 1004); autoresize = W+H; layer = <CALayer: 0xa034780>>
    (lldb) break set -F '-[CALayer setBounds:]' -c '((int*)$esp)[1] == 0xa034780'
    Breakpoint created: 2: name = '-[CALayer setBounds:]', locations = 1, resolved = 1
    

    When the breakpoint is hit, the CALayer instance is referenced by ((int *)$esp)[1], and the new bounds is *(CGRect *)($esp+12):

    (lldb) po ((int*)$esp)[1]
    (int) $8 = 167987072 <CALayer:0xa034780; position = CGPoint (384 480); bounds = CGRect (0 0; 768 1004); delegate = <UIView: 0xa034690; frame = (0 -22; 768 1004); autoresize = W+H; layer = <CALayer: 0xa034780>>; sublayers = (<CALayer: 0xa033010>); backgroundColor = <CGColor 0xa034960> [<CGColorSpace 0xa02b3b0> (kCGColorSpaceDeviceRGB)] ( 1 1 1 1 )>
    (lldb) p *(CGRect*)($esp+12)
    (CGRect) $9 = origin=(x=0, y=0) size=(width=768, height=960)
    (lldb) finish
    (lldb) po 0xa034780
    (int) $10 = 167987072 <CALayer:0xa034780; position = CGPoint (384 480); bounds = CGRect (0 0; 768 960); delegate = <UIView: 0xa034690; frame = (0 0; 768 960); autoresize = W+H; layer = <CALayer: 0xa034780>>; sublayers = (<CALayer: 0xa033010>); backgroundColor = <CGColor 0xa034960> [<CGColorSpace 0xa02b3b0> (kCGColorSpaceDeviceRGB)] ( 1 1 1 1 )>
    

    On the device

    Remember to use the layer address in the breakpoint condition, not the view address.

    (lldb) po self.view
    (UIView *) $0 = 0x1f031a10 <UIView: 0x1f031a10; frame = (0 20; 768 1004); autoresize = W+H; layer = <CALayer: 0x1f031b00>>
    (lldb) break set -F '-[CALayer setBounds:]' -c '$r0 == 0x1f031b00'
    Breakpoint created: 2: name = '-[CALayer setBounds:]', locations = 1, resolved = 1
    

    When the breakpoint is hit, the CALayer instance is referenced by $r0, the new X origin is in $r2, the new Y origin is in $r3, and the new size is *(CGSize *)$sp:

    (lldb) po $r0
    (unsigned int) $7 = 520297216 <CALayer:0x1f031b00; position = CGPoint (384 480); bounds = CGRect (0 0; 768 1004); delegate = <UIView: 0x1f031a10; frame = (0 -22; 768 1004); autoresize = W+H; layer = <CALayer: 0x1f031b00>>; sublayers = (<CALayer: 0x1f030840>); backgroundColor = <CGColor 0x1f031ce0> [<CGColorSpace 0x1e530ad0> (kCGColorSpaceDeviceRGB)] ( 1 1 1 1 )>
    (lldb) p/f $r2
    (unsigned int) $14 = 0
    (lldb) p/f $r3
    (unsigned int) $15 = 0
    (lldb) p *(CGSize *)$sp
    (CGSize) $16 = (width=768, height=960)
    (lldb) finish
    (lldb) po 0x1f031b00
    (int) $17 = 520297216 <CALayer:0x1f031b00; position = CGPoint (384 480); bounds = CGRect (0 0; 768 960); delegate = <UIView: 0x1f031a10; frame = (0 0; 768 960); autoresize = W+H; layer = <CALayer: 0x1f031b00>>; sublayers = (<CALayer: 0x1f030840>); backgroundColor = <CGColor 0x1f031ce0> [<CGColorSpace 0x1e530ad0> (kCGColorSpaceDeviceRGB)] ( 1 1 1 1 )>
    
    0 讨论(0)
  • 2020-12-12 18:26

    On 64 bit simulators the break command should be:

    break set -F '-[CALayer setBounds:]' -c '$rdi == 0x...'
    
    0 讨论(0)
提交回复
热议问题