27

I am running Xcode and I would like to dump out a NSData*. The variable in question is buffer. Is there a way to do this through the UI or the GDB debugger?

This is what I see at runtime

Edit

I've moved my notes into an answer.

pkamb
  • 33,281
  • 23
  • 160
  • 191
Brian
  • 6,910
  • 8
  • 44
  • 82
  • Have you tried "po buffer" in LLDB? – ratbum Jul 17 '12 at 22:03
  • @ratburn I tried that in GDB. I get a number, presumably the address. Doing a google search for LLDB now. – Brian Jul 17 '12 at 22:05
  • Bugger, I'm sure I saw the contents of NSData once and was consequently horrified. I just can't remember how I did it, sorry. – ratbum Jul 17 '12 at 22:23
  • Got it: Right click on NSData in the list displayed there, and click Show Memory Of x. – ratbum Jul 17 '12 at 22:29
  • I'm trying to accomplish the same thing but with a Swift NSData variable... created a another question - http://stackoverflow.com/questions/36825241/viewing-nsdata-contents-in-xcode-swift – Marcus Leon Apr 24 '16 at 15:43

12 Answers12

40

No one has ever correctly answered the question. After 2 years I think it's time for one :)

Assuming you have in your code

NSData* myData;

Then in lldb you type

me read `[myData bytes]` -c`[myData length]`

If the format of the dump is not to your liking you can add '-t ' for example

me read `[myData bytes]` -c`[myData length]` -t int

For more help type

help me read

in lldb

GarMan
  • 1,034
  • 7
  • 10
  • 3
    This is the answer that got me where I needed to be -- NSData with each byte printed as a two-char hex value (AB 01 3F, etc). – Gary Johnson Apr 23 '15 at 03:39
24

From Xcode 5 (lldb), you can use the following:

po (NSString *)[[NSString alloc] initWithData:buffer encoding:4]

Note that this assumes your NSData instance is encoded with NSUTF8StringEncoding, but you can look up the other values in the headers or the documentation.

So if you're debugging something like a JSON request that's wrapped up in an NSURLSessionDataTask, the request data is in task.originalRequest.httpBody, and you can view that in the debugger with

po (NSString *)[[NSString alloc] initWithData:task.originalRequest.HTTPBody encoding:4]
Kevin Clifton
  • 509
  • 5
  • 5
16

In lldb, the following works to let you examine the contents of NSData objects:

You can get the address of the bytes for use with various debugger commands like this:

p (void *)[buffer bytes]

You see something like this:

(void *) $32 = 0x0b5e11f0

If you know the underlying data is a string, you can do this:

p (char *)[buffer bytes]

and the debugger will output:

(char *) $33 = 0x0b5e11f0 "This is the string in your NSData, for example."
Troy
  • 5,319
  • 1
  • 35
  • 41
  • Unfortunately, if the data is long the output will be truncated. @KevinClifton's answer avoids that problem. – ThomasW Aug 20 '15 at 05:57
8

In Swift this should do the trick:

po String(data:buffer!, encoding: NSUTF8StringEncoding)
Max MacLeod
  • 26,115
  • 13
  • 104
  • 132
6

Right click buffer and click on Print description of "buffer".

The console should say

Printing description of buffer:
<your data here ...>
Anshu Chimala
  • 2,800
  • 2
  • 23
  • 22
  • I tried this, but I just get the sentence "Printing description of buffer:" and then no output. – Brian Jul 17 '12 at 22:09
4

Unfortunately, none of the suggestions so far solved the problem of actually being able to quickly display the data inside NSData.

I wrote a simple method that works the way I need it to. From the GDB window, I can type in print [Util dumpData:theData] and I will get nice, formatted output.

+(void) dumpData:(NSData *)data
{
    unsigned char* bytes = (unsigned char*) [data bytes];

    for(int i=0;i< [data length];i++)
    {
        NSString* op = [NSString stringWithFormat:@"%d:%X",i,bytes[i],nil];
        NSLog(@"%@", op);
    }
}

NsLog Output

0:24
1:0
2:4
3:0
4:0
5:0

T'Pol
  • 339
  • 4
  • 9
Brian
  • 6,910
  • 8
  • 44
  • 82
1

Your data instance is empty.

It wouldn't only display the address otherwise. -[NSData description] includes a printout of the contents of the data. The bytes are grouped in fours and printed in hex with a leading 0 placeholder:

char arr[] = {0x1, 0x2, 0xA, 0x4, 0xF};
NSData * dat = [NSData dataWithBytes:arr length:5];
NSLog(@"%@", dat);

2012-07-17 22:24:48.973 PrintDat[61264:403] <01020a04 0f>

Using po dat at the debugger's command line will give you the same results, including the address:

(NSData *) $1 = 0x00007f98da500180 <01020a04 0f>

The contextual menu route that Anshu suggested also uses the description method.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • Josh, It's definitely getting populated but I could be doing it wrong. http://i.imgur.com/FtiE6.png – Brian Jul 17 '12 at 23:23
  • Okay, it looks like it should have 5 bytes in it. What's the `length` (`p (NSUInteger)[buffer length]`), and what's the result of `po buffer` at that breakpoint? – jscs Jul 17 '12 at 23:33
  • At the breakpoint I inspected the contents it should only have 3 bytes and I got "$1 = 3" which is exactly what I was expecting. – Brian Jul 18 '12 at 12:25
1

I think I have it now.

Right click on NSData in the list displayed there, and click 'Show Memory Of "x"'.

ratbum
  • 1,030
  • 12
  • 29
  • 1
    Careful! This is the memory of the _object_, not just the data it wraps, and the display only shows you a certain-size chunk starting at the address of the variable -- not necessarily the whole object and just the object. – jscs Jul 17 '12 at 22:42
  • @JoshCaswell That's what I am seeing - not the data contained in the inner array. – Brian Jul 17 '12 at 23:32
1

I posted this as an answer to this relevant question:

Once you place a breakpoint, run, and the program stops at the breakpoint, hover your cursor over the variable/value you want to see like this:

enter image description here

You could also place an NSLog(@"%@", yourLabel.text); to view the contents of that label/other object type.

One other option is to run GDB in the console like this:

gdb
attach <your process name>

And then use the po (print-object) command to view the value of a variable like this:

po variableName

To view the value of primitive types (int, float, long, double, char, etc.), you can just use the print command while running GDB in the console like this:

print yourPrimitiveVariable

Hope this helps!

EDIT:

With the po command, you can print out the value of an object using both the property name (self.myProperty) or the ivar name (possibly _myProperty). I demonstrate this here:

enter image description here

Community
  • 1
  • 1
pasawaya
  • 11,515
  • 7
  • 53
  • 92
  • So in my console, it looks like it's running GDB and for what it's worth, this is an iOS project. When I issue the po command with an int, it seems to be trying to resolve it as an object. I get "0x4 does not appear to point to a valid object." when the value of the int is 4. – Brian Jul 17 '12 at 23:29
  • 1
    First off, why the down vote. I feel like my answer was very comprehensive and relevant. Second, @rhooligan With `int`'s you use the `print` command. – pasawaya Jul 18 '12 at 02:57
1

Xcode 11.4 (and probably earlier) supports examining the raw bytes of (NS)Data in the visual debugger. Set a breakpoint after the Data has been assigned, hover over the symbol until the popup appears, and click on the eye or info icon. Roll for dexterity to prevent the popup from closing on you by moving outside of the tiny target.

Tested with Swift but presumably works with C family languages, too.

(Note: the eye icon produces the output below which is nicely formatted but, uh... seems to be missing the final column of bytes?)

Xcode data view

Brett
  • 4,341
  • 2
  • 19
  • 17
0

The easiest way for me (during local development only!) is to convert to unused NSString instances. Then the values show right up in the debugger. Once I'm finished, I nuke those lines of code.

From this old thread

NSString* newStr = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];

enter image description here

Community
  • 1
  • 1
quickshiftin
  • 66,362
  • 10
  • 68
  • 89
0

For Swift code I'm doing the following:

When my program is stopped in a breakpoint I use the "Add expression" option and enter [UInt8](data) where data is my Data instance:

enter image description here

After that I can see the data contents:

enter image description here

algrid
  • 5,600
  • 3
  • 34
  • 37