an0
an0

Reputation: 17530

Why can't LLDB print view.bounds?

Things like this drive me crazy when debugging:

(lldb) p self.bounds
error: unsupported expression with unknown type
error: unsupported expression with unknown type
error: 2 errors parsing expression
(lldb) p (CGRect)self.bounds
error: unsupported expression with unknown type
error: unsupported expression with unknown type
error: C-style cast from '<unknown type>' to 'CGRect' is not allowed
error: 3 errors parsing expression
(lldb) p [self bounds]
error: 'bounds' has unknown return type; cast the call to its declared return type
error: 1 errors parsing expression
(lldb) p (CGRect)[self bounds]
(CGRect) $1 = origin=(x=0, y=0) size=(width=320, height=238)
(lldb) You suck!
error: 'You' is not a valid command.
(lldb) …

Why did the first 3 attempts fail? Is there any simpler way to print self.bounds? Thanks.

Upvotes: 57

Views: 13474

Answers (8)

wj2061
wj2061

Reputation: 6885

I tried @an0's answer expr @import UIKit, but it didn't work.

Then I added a pch file, and add these lines of code in the file:

#ifndef PrefixHeader_pch
#define PrefixHeader_pch

#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif

#endif /* PrefixHeader_pch */    

Next, link the pch file to my project:

enter image description here

Run the app again, then I can use the dot notation in lldb console:

(lldb) po self.view.bounds    

For how to add a pch file , see the answer here PCH File in Xcode 6

Upvotes: 0

onmyway133
onmyway133

Reputation: 48055

You gonna love Xcode 6.3+

TLDR

(lldb) e @import UIKit
(lldb) po self.view.bounds

LLDB's Objective-C expression parser can now import modules. Any subsequent expression can rely on function and method prototypes defined in the module:

(lldb) p @import Foundation
(lldb) p NSPointFromString(@"{10.0, 20.0}");
(NSPoint) $1 = (x = 10, y = 20)

Before Xcode 6.3, methods and functions without debug information required explicit typecasts to specify their return type. Importing modules allows a developer to avoid the more labor-intensive process of determining and specifying this information manually:

(lldb) p NSPointFromString(@"{10.0, 20.0}");
error: 'NSPointFromString' has unknown return type; cast the call to its declared return type
error: 1 errors parsing expression
(lldb) p (NSPoint)NSPointFromString(@"{10.0, 20.0}”);
(NSPoint) $0 = (x = 10, y = 20)

Other benefits of importing modules include better error messages, access to variadic functions when running on 64-bit devices, and eliminating potentially incorrect inferred argument types.

PS: If you also confuse p vs po

p == print == expression -- == e --
po == expression -O -- == e -O --

-- is the separator between command+flag vs inputs

-O flag is for invoking the object description method

Upvotes: 15

an0
an0

Reputation: 17530

Starting from Xcode 6.3, we have a better solution. In short, you need to import UIKit for LLDB to know about these types: expr @import UIKit. Check out this article to learn some tricks to make your life even easier.

Upvotes: 41

Ozgur Sahin
Ozgur Sahin

Reputation: 1453

With Xcode 6.3, we can import UIKit and then print the frame or bound of view

expr @import UIKit
p self.view.bounds

Upvotes: 8

youfu
youfu

Reputation: 1627

You can access it by

p (CGRect)[view bounds]

or

p view.layer.bounds

view.bounds is actually view.layer.bounds

It seems that the type info of [UIView bounds] is not available to lldb

Upvotes: 57

Bhavik Modi
Bhavik Modi

Reputation: 1565

Try with following expression,

p self.view.bounds.size.width

or use,

po self.view

p - Print is only uses to print normal/simple values while, po - Print Object works same as NSLog to print value of an object

Upvotes: 0

Bryan Chen
Bryan Chen

Reputation: 46568

I don't know what was the context when you running this. But looks like lldb cannot find the type of self.

In order for lldb to evaluate self.bounds, it need to know the type of self is some Class has property bounds. It cannot assume self is ObjC type because you may call it under such context:

void test()
{
    struct 
    {
        int bounds;
    } self;
}

so you get the error error: unsupported expression with unknown type

However, if you call it using [self bounds], lldb knows that self much be ObjC type because [] syntax only apply to ObjC type. But since the type of self is not clear, it still cannot evaluate the result of [self bounds] so you need to cast it to CGRect

Upvotes: 0

Gabriele Petronella
Gabriele Petronella

Reputation: 108091

LLDB does not support dot notation for message sending when using p and that's why

p self.bounds

doesn't work, but

p [self bounds]

does.

(It actually supports it for objects when you use po, though)

Also, LLDB doesn't have type information of non-objects available at runtime, so you need to explicitly provide a type by casting the return value.

Upvotes: 6

Related Questions