[lldb-dev] Strange behavior with summary function

Bruce Mitchener bruce.mitchener at gmail.com
Fri Jun 20 07:17:33 PDT 2014


Of course, I ended up figuring this out. I wasn't adding 1 to the size, so
I wasn't reading the NULL into the SBData, so when calling |GetString| on
the SBData, it was randomly failing. I suspect that perhaps
SBData::GetString can read one past the end of the buffer, so sometimes it
was a NULL and sometimes not?

It would be nice / more usable if the error in this situation indicated
that the data wasn't NULL-terminated rather than a generic "unable to read
data".

At any rate, with this fixed, things look much better. :)

 - Bruce

On Fri, Jun 20, 2014 at 6:04 PM, Bruce Mitchener <bruce.mitchener at gmail.com>
wrote:

> Hello,
>
> I'm working on providing some LLDB integration for the Dylan language (
> http://opendylan.org/).
>
> I've tried using both the versions of lldb that ship with the current
> release of Xcode5 (lldb-310.2.37) as well as the version that ships with
> the Xcode6 beta (lldb-320.3.100).
>
> For what I'm currently testing, we generate C which is then compiled by
> clang.
>
> We have
>
>     typedef void*                   dylan_value;
>     typedef struct _dylan_byte_string_0 {
>       dylan_value class;
>       dylan_value size;
>       char data[_size + 1];
>     } dylan_byte_string;
>
> The strange behavior is this:
>
> (lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $2 = 0x005477c8 {<error: unable to read data>}
> (lldb) print
> (dylan_value)Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $3 = 0x005477c8 {<byte-string>: size: 0}
> (lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $4 = 0x005477c8 {<error: unable to read data>}
> (lldb) print
> (dylan_value)Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $5 = 0x005477c8 {<error: unable to read data>}
> (lldb) print
> (dylan_byte_string*)Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_byte_string *) $6 = 0x005477c8 {<byte-string>: size: 19, data:
> accessor-read-into!}
>
> Note that there should be no difference between $2, $3, $4 or $5. The
> value is a dylan_value but notice that in instance $3, it says the size was
> 0, so it was able to read the data (although incorrectly).  When I cast it
> through to the "dylan_byte_string*", it read the data correctly.
>
> The Python code for dealing with a string is:
>
>   def dylan_byte_string_summary(value, dict):
>     size = value.GetChildMemberWithName('size').GetValueAsUnsigned() >> 2
>     if size == 0:
>       return '{<byte-string>: size: 0}'
>     else:
>       data = get_byte_string_data(value)
>       return '{<byte-string>: size: %d, data: %s}' % (size, data)
>
>   def get_byte_string_data(value):
>     target = lldb.debugger.GetSelectedTarget()
>     byte_string_type =
> target.FindFirstType('dylan_byte_string').GetPointerType()
>     value = value.Cast(byte_string_type)
>     size = value.GetChildMemberWithName('size').GetValueAsUnsigned() >> 2
>     if size == 0:
>       return ''
>     data = value.GetChildMemberWithName('data').GetPointeeData(0, size)
>     error = lldb.SBError()
>     string = data.GetString(error, 0)
>     if error.Fail():
>       return '<error: %s>' % error.GetCString()
>     else:
>       return '%s' % string
>
> The relevant configuration is done here:
>
>   debugger.HandleCommand('type summary add dylan_byte_string -F
> dylan.dylan_byte_string_summary -w dylan')
>   debugger.HandleCommand('type summary add dylan_value -F
> dylan.dylan_value_summary -w dylan')
>
> When we call dylan_value_summary, we check to see if it is a tagged
> integer otherwise we dig out the class pointer, get the name of the class
> and then dispatch to the appropriate summary function ... so when we get
> results like $2, $4 and $5 above, that means we got an error trying to read
> the class name. I don't understand how we can get error #3.
>
> In fact, on a subsequent run of the debugger, I just tried printing the
> exact same thing a couple of times without type casts:
>
> (dylan_value) $0 = 0x005477c8 {<byte-string>: size: 19, data: <error:
> unable to read data>}
> (lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $1 = 0x005477c8 {<error: unable to read data>}
> (lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $2 = 0x005477c8 {<error: unable to read data>}
> (lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $3 = 0x005477c8 {<error: unable to read data>}
> (lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $4 = 0x005477c8 {<error: unable to read data>}
> (lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $5 = 0x005477c8 {<byte-string>: size: 19, data:
> accessor-read-into!}
>
> My favorite one is this one though, as I can't even see how that's
> possible given my code:
>
> (lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_
> (dylan_value) $15 = 0x005477c8 {<byte-string>}
>
> Does anyone have any idea about this?
>
> Thanks,
>
>  - Bruce
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140620/ea356a17/attachment.html>


More information about the lldb-dev mailing list