> On Oct 22, 2021, at 6:12 AM, Pavel Labath via lldb-dev 
> <lldb-dev@lists.llvm.org> wrote:
> 
> Hello Jim, everyone,
> 
> I recently got a question/bug report about python pretty printers (synthetic 
> child providers) that I couldn't answer.
> 
> The actual script is of course more complicated, but the essence boils down 
> to this.
> 
> There's a class, something like:
> struct S {
>  ...
>  T member;
> };
> 
> The pretty printer tries to print this type, and it does something like:
>     def get_child_at_index(self, index):
>         if index == 0:
>             child = self.sbvalue.GetChildMemberWithName("child")
>             return child.CreateChildAtOffset("[0]", 0, T2)
> 
> 
> Now here comes the interesting part. The exact behaviour here depends on the 
> type T. If T (and of course, in the real example this is a template) is  
> plain type, then this behaves a like a bitcast so the synthetic child is 
> essentially *reinterpret_cast<T2*>(&s.member).
> 
> *However*, if T is a pointer, then lldb will *dereference* it before 
> performing the cast, giving something like
>   *reinterpret_cast<T2*>(s.member) // no &
> as a result.
> 
> The first question that comes to mind is: Is this behavior intentional or a 
> bug?
> 
> At first it seemed like this is too subtle to be a bug, but the more I though 
> about it, the less I was sure about the CreateChildAtOffset function as a 
> whole.
> 
> What I mean is, this pretty printer is essentially creating child for a value 
> that it is not printing. That seems like a bad idea in general, although I 
> wasn't able to observe any ill effects (e.g. when I printi s.member directly, 
> I don't see any bonus children). Then I looked at some of the in-tree 
> pretty-printers, and I did find this pattern at least two libc++ printers 
> (libcxx.py:125 and :614), although they don't suffer from this ambiguity, 
> because the values they are printing are always pointers.
> 
> However, that means I absolutely don't know what is the expected behavior 
> here:
> - Are pretty printers allowed to call CreateChildAtOffset on values they are 
> not printing

This should be fine yes AFAIK.

> - Is CreateChildAtOffset supposed to behave differently for pointer types?

yes. It all comes down to what a child of a specific type would be. For 
pointers or references, you do want it to be at an offset from what it is 
pointing to. If you have an array of bytes, then you want it to be an offset 
within that array. 

I would be really bad to take a pointer and create a child at offset and not 
follow the pointer by taking the next thing past the pointer. Like if you have:

struct A {
  Foo *ptr1;
  Bar *ptr2;
}

And if we have a "ptr1" in a  SBValue, and asked it to CreatChildAtOffset(), we 
would never really want to access "ptr2" because we could just ask for "ptr2" 
if we wanted it. 

> 
> I'd appreciate any insight,
> Pavel
> _______________________________________________
> lldb-dev mailing list
> lldb-dev@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

_______________________________________________
lldb-dev mailing list
lldb-dev@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

Reply via email to