Note that there are some explanatory texts on larger screens.

plurals
  1. POPointer arithmetic in LLDB Python scripts
    text
    copied!<p>I've been trying to create a custom data formatter for a custom string type in Xcode. The following code gets me the address of the first character in the string:</p> <pre><code>def MyStringSummary(valobj, internal_dict): data_pointer = valobj.GetChildMemberWithName('AllocatorInstance').GetChildMemberWithName('Data') print data_pointer.GetValue() </code></pre> <p>That prints out the pointer address. When I look at the contents of that address I can see the wide chars used to store that data, so I guess what I have to do is cast this pointer to <code>wchar_t</code> and then I've got the first character. One of my first approaches was this:</p> <pre><code>if data_pointer.TypeIsPointerType(): mychar = data_pointer.Dereference() print mychar.GetValue() else: print "data_pointer is not a pointer!" </code></pre> <p>This confirmed that the data_pointer <em>is</em> a pointer, but the <code>Dereference()</code> call doesn't seem to resolve anything: <code>mychar.GetValue()</code> just returns <code>None</code>. Another issue - would I then be able to go through a loop and increase the address of <code>data_pointer</code> by a fixed amount each time and keep dereferencing and finding the next character, then adding it to the output string? If so, how would I do this?</p> <p>EDIT:</p> <p>To help clarify the problem, I'll post some info about the underlying data structure of the string. The definition is too long to post here (also it inherits most of what it does from a generic array base class) but I'll give some more details.</p> <p>When looking at the <code>StringVar.AllocationInstance.Data</code> pointer location I can see that we're using 16 bits for each character. All of the characters in the string I'm looking at are only 8 bits, with another 8 bits of 0 after each character. So, this is what happens when I do this in the debugger:</p> <pre><code>(lldb) p (char*)(StringVar.AllocatorInstance.Data) (char *) $4 = 0x10653360 "P" (lldb) p (char*)(StringVar.AllocatorInstance.Data)+1 (char *) $6 = 0x10653361 "" (lldb) p (char*)(StringVar.AllocatorInstance.Data)+2 (char *) $7 = 0x10653362 "a" </code></pre> <p>So I assume the reason it's only showing one character at a time is because it thinks each 8-bit character is null-terminated by the following 8 bits. However, when I cast to <code>unsigned short</code> I get this:</p> <pre><code>(lldb) p (unsigned short*)(StringVar.AllocatorInstance.Data) (unsigned short *) $9 = 0x10653360 (lldb) p *(unsigned short*)(StringVar.AllocatorInstance.Data) (wchar_t) $10 = 80 (lldb) p (char*)(unsigned short*)(StringVar.AllocatorInstance.Data) (char *) $11 = 0x10653360 "P" (lldb) p (char*)((unsigned short*)(StringVar.AllocatorInstance.Data)+1) (char *) $14 = 0x10653362 "a" (lldb) p (char*)((unsigned short*)(StringVar.AllocatorInstance.Data)+2) (char *) $18 = 0x10653364 "r" </code></pre> <p>...so it looks like the cast to <code>unsigned short</code> is fine, as long as we cast each integer to a char. Any idea how I might try to put this in a Python data formatter?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload