[lldb-dev] Trying to understand symbol importing and its relationship to ASTs

Randy Smith rdsmith at chromium.org
Tue Jul 22 11:41:30 PDT 2014


I'm chasing a crash in lldb, and my current "that doesn't seem right" has
to do with a conflict between a decl and its origin decl (the
transformation done at the beginning of
tools/lldb/source/Expression/ClangASTSource.cpp:ClangASTSource::layoutRecordType()).
 So I'm trying to understand how decls and origin decls get setup during
the symbol import process.  Can anyone give me a sketch/hand?  Specific
questions include:
* There are multiple ASTContexts involved (e.g. the src and dst contexts in
the signature of
tools/lldb/source/Symbol/ClangASTImporter.cpp:ClangASTImporter::CopyType);
do those map to compilation units, or to shared library modules?  Is there
a simple way to tell what CU/.so an ASTContext maps to?
* Does a decl always have an origin decl, even if it was loaded from an
ASTContext (?) that has a complete definition?
* When an origin decl is looked up, should all the types in it be
completed, or might it have incomplete types?  It seems as if there is code
assuming that these types will always be complete.

Context (warning, gets detailed, possibly with irrelevant details because
newbie): lldb is crashing in clang::ASTContext::getASTRecordLayout with the
assertion "Cannot get layout of forward declarations!".  The type in
question is an incomplete type (string16, aka. basic_string<unsigned short,
...>).  Normally clang::ASTContext::getASTRecordLayout() would call
getExternalSource()->CompleteType() to complete the type, but in this case
it isn't because the type is marked as !hasExternalLexicalStorage().

The *weird* thing is that the type has previously been completed, further
up the stack, but in a different AST node (same name).  In more detail:
Class A contains an instance of class B contains an instance of class C
(==string16).  I'm seeing getASTRecordLayout called on class A, which then
calls it (indirectly, though the EmptySubobjectMap construtor) on class B,
which then calls it (ditto) on class C (all works).  Then the stack unwinds
up to the B call, which proceeds to the Builder.Layout() line in that
function.  It ends up (through the transformation mentioned above in
clang::ClangASTSource::LayoutRecordType()) calling getASTRecordLayout() on
the origin decl.  When it recurses down to class C, that node isn't
complete, isn't completed, and causes an assertion.  So I'm trying to
figure out whether the problem is that any decl hanging off an origin_decl
should be complete, or that that node shouldn't be marked as
!hasExternalLexicalStorage().  (Or something else; I've already gone
through several twists and turns debugging this problem :-}.)

The crash is reproducible, but one of the reproduction steps is "Build
chrome", so I figured I'd work on it some myself to teach myself lldb
rather than try to file a bug on it.   The wisdom of that choice in
question :-}.

Any thoughts anyone has would be welcome.

-- Randy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140722/0ee2858c/attachment.html>


More information about the lldb-dev mailing list