In LLDB we create clang::ASTContext objects for the modules (executable and 
shared libraries), one for the target to contain the expression results, and 
one for each expression.

When we evaluate an expression we might do something like:

(lldb) expr a + b

where "a" is from liba.so and "b" is from libb.so. We must copy types from the 
clang::ASTContext for each module, so we will copy the type of "a" into the 
expression clang::ASTContext and we will also copy type "b" from the 
clang::ASTContext from libb.so into the expression clang::ASTContext. Many 
times we the same types, but one has more information in it. Like lets say both 
"a" and "b" are type "foo<int>". We can often end up with different definitions 
of "foo<int>" in liba.so and libb.so and when we try to copy the types, we 
first copy "foo<int>" from liba.so into the expression AST, and then we do the 
same with "b" from libb.so, but it notices that the types are the same level, 
so it tries to verify the types are the same. This often fails due to debug 
info being more complete in one of the shared libraries. One example is the 
compiler might omit the complete definition for a base class in libb.so where 
it has a complete definition for the base class in liba.so. When parsing types 
we must always give clang something it is happy with, so if we run into debug 
info that has a complete definition for "foo<int>", but it inherits from class 
"C". So the definition for "C" in liba.so is:

class C
{
public:
    C();
    ~C();
    int callme();
};

and "C" in "libb.so" is just a forward declaration:

class C;

But then int libb.so we must create a type for foo<int> but we can't since C 
isn't complete, but we do anyway by just saying C looks like:

class C
{
};

So now we have two types that differ, and importing both foo<int> types into 
the expression clang::ASTContext will fail. This happens a lot for C++ template 
classes because of the haphazard way that compilers generate debug info for 
templates. It could be a bug in the type importer where the two types are 
actually the same, but the type importer thinks they are different, but often 
it is because the types actually do differ. 

One way to get around the compiler emitting forward declarations to base 
classes is to specify: -fno-limit-debug-info

This will disable the debug info minimizing feature and make the compiler emit 
more complete debug info and it might fix your problem.

Greg Clayton

> On Oct 13, 2015, at 10:44 AM, Ramkumar Ramachandra via lldb-dev 
> <lldb-dev@lists.llvm.org> wrote:
> 
> Hi,
> 
> At one point in the debugging session, I get this when I try to print
> a particular value:
> 
> error: field '__r_' declared with incompatible types in different
> translation units
> ('std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >' vs.
> 'std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >')
> error: field '__r_' declared with incompatible types in different
> translation units
> ('std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >' vs.
> 'std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >')
> error: field '__r_' declared with incompatible types in different
> translation units
> ('std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >' vs.
> 'std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >')
> error: field '__r_' declared with incompatible types in different
> translation units
> ('std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >' vs.
> 'std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >')
> note: declared here with type
> 'std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >'
> note: declared here with type
> 'std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >'
> note: declared here with type
> 'std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >'
> note: declared here with type
> 'std::__1::__compressed_pair<std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
> std::__1::allocator<char> >'
> 
> (which makes no sense at all; lhs and rhs are identical)
> 
> After that point, whatever I try to print returns this error.
> 
> What is going on?
> 
> Thanks.
> 
> Ram
> _______________________________________________
> lldb-dev mailing list
> lldb-dev@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

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

Reply via email to