[lldb-dev] Strange behavior with summary function

Bruce Mitchener bruce.mitchener at gmail.com
Fri Jun 20 04:04:55 PDT 2014


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/858e902c/attachment.html>


More information about the lldb-dev mailing list