[lldb-dev] Using data formatters to display QString
Eran Ifrah
eran.ifrah at gmail.com
Tue Apr 29 06:50:15 PDT 2014
Hi Enrico and all,
Thanks for the references, it helped me a lot.
I am now able to view QString within lldb from the *command line*, but not
from within my plugin :P (this was my intention all the way)
I created the following 2 files:
~/.lldbinit, with this single line:
command script import /home/eran/.lldb/qstring.py
In the script: ~/.lldb/qstring.py, I placed the following content (a
slightly modified printer based on your example):
import lldb
def utf16string_summary(value, *rest):
f = open('/tmp/py.log','w+b')
f.write('inside utf16string_summary\n')
f.close()
str_data =
value.GetChildMemberWithName("d").GetChildMemberWithName("data")
length_vo =
value.GetChildMemberWithName("d").GetChildMemberWithName("size")
length = length_vo.GetValueAsUnsigned(0)
if length == 0:
return '""'
data = str_data.GetPointeeData(0, length)
error = lldb.SBError()
bytes = data.ReadRawData(error, 0, 2*length)
return '"%s"' % (bytes.decode('utf-16').encode('utf-8'))
def __lldb_init_module(debugger, *rest):
summary =
lldb.SBTypeSummary.CreateWithFunctionName("qstring.utf16string_summary")
summary.SetOptions(lldb.eTypeOptionHideChildren)
debugger.GetDefaultCategory().AddTypeSummary(
lldb.SBTypeNameSpecifier("QString", False), summary )
This setup works when I am using lldb-3.5 from the command line (i.e.
QString is displayed in the following format: m_stringMemeber = "some
content")
Now, this is how I set it up from within my plugin:
I tried both:
m_debugger = lldb::SBDebugger::Create(true); // source init files
and I have also tried this:
m_debugger = lldb::SBDebugger::Create();
...
lldb::SBCommandReturnObject ret;
m_debugger.GetCommandInterpreter().HandleCommand("command source
/home/eran/.lldbinit", ret);
if ( !ret.Succeeded() ) {
// print error here if any
}
Both did not have any affect, i.e. when I view the content of QString in
the IDE, I don't see the summary as it should
Any hints?
Thanks
On Tue, Apr 29, 2014 at 3:38 AM, Enrico Granata <egranata at apple.com> wrote:
> On Apr 28, 2014, at 3:01 PM, Poenitz Andre <Andre.Poenitz at digia.com>
> wrote:
>
>
> Enrico Granata wrote:
> > Eran Ifrah wrote:
> > You can't use expressions in summary strings.
> > We have thought about this several times and have a couple ideas on how
> > it could be done but for now it's not there.
> >
> > If you need to resort to an expression, you can use a python formatter
> > instead and then you are free to call as many expressions as you like.
> >
> > However, this will cause a slowdown - running expressions is not
> > free - and if you ever need to make sure nothing is altering your
> > program state, running expressions might not be a safe bet.
> > Is there really no other way to get to those UTF8 bytes?
>
> QString is stored in UTF16 internally. It can be accessed directly
> through structure member access and pointer arithmetic and converted
> using Python. "Running expressions" is not needed.
>
> Andre'
>
>
> Here’s a small example for general reference:
> Assume I have the following data structure:
>
> #include <string>
> #include <memory>
>
> class UTF16String {
> public:
> UTF16String (const char16_t *data) {
> len = std::char_traits<char16_t>::length(data);
> str_data.reset(new char16_t[len]);
> memcpy(str_data.get(),data,sizeof(char16_t)*(len+1));
> }
>
> private:
> std::unique_ptr<char16_t[]> str_data;
> size_t len;
> };
>
> int main() {
> UTF16String string {u"Just some data in UTF16 here"};
> return 0;
> }
>
>
> This is what it looks like “raw” on OS X:
> (UTF16String) string = {
> str_data = {
> __ptr_ = {
> std::__1::__libcpp_compressed_pair_imp<char16_t *,
> std::__1::default_delete<char16_t> > = {
> __first_ = 0x00000001001037e0
> }
> }
> }
> len = 28
> }
>
> To define a formatter for it you essentially want to grab two elements:
> the data pointer (__first_ = 0x00000001001037e0) and the length (len = 30)
> In our example, the length is defined in UTF16-characters rather than
> bytes. This is something you want to know when writing a formatter
>
> So let’s delve right in:
> def utf16string_summary(value,*rest):
> str_data =
> value.GetChildMemberWithName("str_data").GetChildMemberWithName("__ptr_").GetChildMemberWithName("__first_")
> length_vo = value.GetChildMemberWithName("len")
>
> Now we have SBValues for the string data and for the length - we want the
> “number stored inside” the length:
> length = length_vo.GetValueAsUnsigned(0)
> if length == 0:
> return '""'
>
> As a special case - if the length is zero, just return an empty string. I
> am not going to go in detail over all the possible checks here (hint: what
> if str_data’s value is zero?)
>
> Now let’s grab the bytes - we want length char16_t at the location pointed
> to by our str_data:
> data = str_data.GetPointeeData(0,length)
>
> And now let’s grab a Python string out of those bytes:
> error = lldb.SBError()
> bytes = data.ReadRawData(error,0,2*length)
>
> The 2*length argument is *carefully* crafted to ensure we get all the
> bytes we need - it of course depends on sizeof(char16_t) == 2
>
> Python is pretty good at string management, all we have to do now is tell
> it to turn our string from UTF16 into UTF8:
> return '"%s"' % (bytes.decode('utf-16').encode('utf-8'))
>
> You’re done. To add the summary automatically to LLDB whenever you command
> script import the python file with the formatter:
> def __lldb_init_module(debugger,*rest):
> summary =
> lldb.SBTypeSummary.CreateWithFunctionName("qstring.utf16string_summary")
> summary.SetOptions(lldb.eTypeOptionHideChildren)
>
> debugger.GetDefaultCategory().AddTypeSummary(lldb.SBTypeNameSpecifier("UTF16String",False),summary)
>
> This is what you get with the summary enabled:
> (UTF16String) string = "Just some data in UTF16 here”
>
> Find the C++ and the Python parts of the example attached for reference -
> and of course feel free to ping back with any additional questions
>
>
>
>
> *- Enrico*
> 📩 egranata@.com ☎️ 27683
>
>
>
>
>
--
Eran Ifrah
Author of codelite, a cross platform open source C/C++ IDE:
http://www.codelite.org
wxCrafter, a wxWidgets RAD: http://wxcrafter.codelite.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140429/88d8f8c6/attachment.html>
More information about the lldb-dev
mailing list