<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">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?</div>
<div class="gmail_quote"><br></div><div class="gmail_quote">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".</div>
<div class="gmail_quote"><br></div><div class="gmail_quote">At any rate, with this fixed, things look much better. :)</div><div class="gmail_quote"><br></div><div class="gmail_quote"> - Bruce</div><div class="gmail_quote">
<br></div><div class="gmail_quote">On Fri, Jun 20, 2014 at 6:04 PM, Bruce Mitchener <span dir="ltr"><<a href="mailto:bruce.mitchener@gmail.com" target="_blank">bruce.mitchener@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Hello,<div><br></div><div>I'm working on providing some LLDB integration for the Dylan language (<a href="http://opendylan.org/" target="_blank">http://opendylan.org/</a>).</div><div><br></div><div>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).</div>

<div><br></div><div>For what I'm currently testing, we generate C which is then compiled by clang.</div><div><br></div><div>We have </div><div><br></div><div>    typedef void*                   dylan_value;<br></div>
<div>
<div>    typedef struct _dylan_byte_string_0 {</div><div>      dylan_value class;</div><div>      dylan_value size;</div><div>      char data[_size + 1];</div><div>    } dylan_byte_string;</div></div><div><br></div><div>
The strange behavior is this:</div>
<div><br></div><div><div>(lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div><div>(dylan_value) $2 = 0x005477c8 {<error: unable to read data>}</div><div>(lldb) print (dylan_value)Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div>

<div>(dylan_value) $3 = 0x005477c8 {<byte-string>: size: 0}</div><div>(lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div><div>(dylan_value) $4 = 0x005477c8 {<error: unable to read data>}</div>

<div>(lldb) print (dylan_value)Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div><div>(dylan_value) $5 = 0x005477c8 {<error: unable to read data>}</div><div>(lldb) print (dylan_byte_string*)Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div>

<div>(dylan_byte_string *) $6 = 0x005477c8 {<byte-string>: size: 19, data: accessor-read-into!}</div></div><div><br></div><div>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.</div>

<div><br></div><div>The Python code for dealing with a string is:</div><div><br></div><div><div>  def dylan_byte_string_summary(value, dict):</div><div>    size = value.GetChildMemberWithName('size').GetValueAsUnsigned() >> 2</div>

<div>    if size == 0:</div><div>      return '{<byte-string>: size: 0}'</div><div>    else:</div><div>      data = get_byte_string_data(value)</div><div>      return '{<byte-string>: size: %d, data: %s}' % (size, data)</div>

</div><div><br></div><div><div>  def get_byte_string_data(value):</div><div>    target = lldb.debugger.GetSelectedTarget()</div><div>    byte_string_type = target.FindFirstType('dylan_byte_string').GetPointerType()</div>

<div>    value = value.Cast(byte_string_type)</div><div>    size = value.GetChildMemberWithName('size').GetValueAsUnsigned() >> 2</div><div>    if size == 0:</div><div>      return ''</div><div>    data = value.GetChildMemberWithName('data').GetPointeeData(0, size)</div>

<div>    error = lldb.SBError()</div><div>    string = data.GetString(error, 0)</div><div>    if error.Fail():</div><div>      return '<error: %s>' % error.GetCString()</div><div>    else:</div><div>      return '%s' % string</div>

</div><div><br></div><div>The relevant configuration is done here:</div><div><br></div><div><div>  debugger.HandleCommand('type summary add dylan_byte_string -F dylan.dylan_byte_string_summary -w dylan')</div><div>

  debugger.HandleCommand('type summary add dylan_value -F dylan.dylan_value_summary -w dylan')<br></div></div><div><br></div><div>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.</div>

<div><br></div><div>In fact, on a subsequent run of the debugger, I just tried printing the exact same thing a couple of times without type casts:</div><div><br></div><div><div>(dylan_value) $0 = 0x005477c8 {<byte-string>: size: 19, data: <error: unable to read data>}</div>

<div>(lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div><div>(dylan_value) $1 = 0x005477c8 {<error: unable to read data>}</div><div>(lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div>

<div>(dylan_value) $2 = 0x005477c8 {<error: unable to read data>}</div><div>(lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div><div>(dylan_value) $3 = 0x005477c8 {<error: unable to read data>}</div>

<div>(lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div><div>(dylan_value) $4 = 0x005477c8 {<error: unable to read data>}</div><div>(lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div>

<div>(dylan_value) $5 = 0x005477c8 {<byte-string>: size: 19, data: accessor-read-into!}</div></div><div><br></div><div>My favorite one is this one though, as I can't even see how that's possible given my code:</div>

<div><br></div><div><div>(lldb) print Kaccessor_read_intoXYstreams_internalsVio.debug_name_</div><div>(dylan_value) $15 = 0x005477c8 {<byte-string>}</div></div><div><br></div><div>Does anyone have any idea about this?</div>

<div><br></div><div>Thanks,</div><div><br></div><div> - Bruce</div><div><br></div></div>
</blockquote></div><br></div></div>