Re: lldb 'print object' (po) prints pointer value if not object?
Re: lldb 'print object' (po) prints pointer value if not object?
- Subject: Re: lldb 'print object' (po) prints pointer value if not object?
- From: email@hidden
- Date: Wed, 23 Apr 2014 10:42:00 -0700
If you want to avoid this confusion with the present tools, you can use the "full" po printing option, which will show both the value of the expression and the description result. So for instance:
(lldb) po selection
<__NSArrayI 0x10066b810>(
{
...
}
but:
(lldb) expr -v full -O -- selection
(NSArray *) $8 = 0x000000010066b810 <__NSArrayI 0x10066b810>(
{
...
}
The first part is the value of the expression, and the description follows. If there were no description, then you would see:
(lldb) expr -vfull -O -- (id) 0x35
(id) $9 = 0x0000000000000035
so you can clearly tell that the expression had a value, but no description. If you like this form better, then just put:
command unalias po
command alias po expression -vfull -O --
in your ~/.lldbinit file.
Jim
On Apr 23, 2014, at 7:37 AM, Kate Stone <email@hidden> wrote:
> When LLDB is given an expression with "po" it attempts to print a description for the object reference returned by the expression. Prior to Xcode 5 it would fail when a non-object value was provided, but some users found it frustrating because they weren't entirely clear about the difference between "p" and "po". So in Xcode 5 we changed the behavior to fall back to "p" when the value provided isn't an object. Doing so silently obviously creates situations like this that are potentially confusing.
>
> I've logged a suggestion that we clearly distinguish between the two cases.
>
> Kate Stone email@hidden
> Xcode Runtime Analysis Tools
>
> On Apr 23, 2014, at 3:19 AM, Bavarious <email@hidden> wrote:
>
>> On 23 Apr 2014, at 02:47, Quincey Morris <email@hidden> wrote:
>>> The tagged pointer for NSNumber 83 is 0x5327, I just found with test code.
>>
>> One minor note: there are different possible representations for a given integer as a tagged pointer depending on the underlying integer type used to build the NSNumber instance:
>>
>> NSNumber *n0 = [NSNumber numberWithChar:83];
>> NSNumber *n1 = [NSNumber numberWithShort:83];
>> NSNumber *n2 = [NSNumber numberWithInt:83];
>> NSNumber *n3 = [NSNumber numberWithLong:83];
>>
>> NSLog(@"%p %p %p %p", n0, n1, n2, n3);
>>
>> outputs
>>
>> 0x5307 0x5317 0x5327 0x5337
>>
>> on Mavericks.
>>
>> When representing an integer NSNumber as a tagged pointer, its LSBs are (in binary):
>>
>> 1: tagged pointer flag
>> 011: tag index for NSNumber
>> xxxx: representation of its original type, e.g. 0000 for 8-bit/char integers
>> remainder: payload with actual number.
>>
>> So
>>
>> 0x5307 = 1010011 0000 011 1 (83 as an 8-bit/char NSNumber tagged pointer)
>> 0x5317 = 1010011 0001 011 1 (83 as a 16-bit/short NSNumber tagged pointer)
>> 0x5327 = 1010011 0010 011 1 (83 as a 32-bit/int NSNumber tagged pointer)
>> 0x5337 = 1010011 0011 011 1 (83 as a 64-bit/long NSNumber tagged pointer)
>>
>> These representations are internal and can change without notice—in fact, they already have since the introduction of tagged pointers in Lion.
>>
>> ---
>>
>> As for whether 83 is a valid tagged pointer, its tag index would be 0b001, which isn’t documented in objc4/runtime/objc-internal.h. A simple program trying to use it directly crashes with a segmentation fault:
>>
>> id o83 = (void *)83;
>> NSLog(@"%@ %@", o83, [o83 class]);
>>
>> Tags 0b001 and 0b111 are the only two tags that are not documented in objc4/runtime/objc-internal.h, which lists
>>
>> OBJC_TAG_NSAtom = 0,
>> OBJC_TAG_1 = 1,
>> OBJC_TAG_NSString = 2,
>> OBJC_TAG_NSNumber = 3,
>> OBJC_TAG_NSIndexPath = 4,
>> OBJC_TAG_NSManagedObjectID = 5,
>> OBJC_TAG_NSDate = 6,
>> OBJC_TAG_7 = 7
>>
>> OBJC_TAG_1 and OBJC_TAG_7 are used in objc4/test/taggedPointers.m to register a user-defined base class and a derived class as tagged: http://www.opensource.apple.com/source/objc4/objc4-551.1/test/taggedPointers.m
>>
>> —--
>>
>> That being said, I get the following from LLDB 310.2.37 after loading an Objective-C program:
>>
>> (lldb) po 0
>> <nil>
>>
>> (lldb) po 1
>> <object returned empty description>
>>
>> (lldb) po 2
>> 2
>>
>> (lldb) po 3
>> 3
>>
>> (lldb) po 42
>> 42
>>
>> (lldb) po 83
>> 83
>>
>> (lldb) po 0x5307
>> 83
>>
>> If I test these numbers with
>>
>> po [(id)<#numberHere> class]
>>
>> I get nil for 0, <object returned empty description> for 1, and __NSCFNumber for 0x5307. The others (2, 3, 42, 83) yield
>>
>> error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x2).
>> The process has been returned to the state before expression evaluation.
>>
>> I have no idea of what’s going on with LLDB. It does look like a bug indeed.
>>
>> FWIW, 1 is an NSAtom tagged pointer (NSAtom’s tag index is 0b000). I don’t know whether it’s a valid representation.
>>
>>
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Xcode-users mailing list (email@hidden)
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Xcode-users mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden