LLDB Expression Parser

I have been familiarizing myself with the expression parsing code in LLDB with the intention of finding and fixing several expression parser related bugs.

The first issue that I have been investigating in detail is related to calling c_str() on a standard string. The expression fails because LLDB is not able to match up the mangled function name with any names in the symbol table. There is special handling for standard strings in IRForTarget::GetFunctionAddress to support two variants of the mangled name prefix of, _ZNKSbIc and _ZNKSs. The _ZNKSbIc represents basic_string<char> whereas _ZNKSs represents string which is a typedef of basic_string<char>. In this case the full name in the g++ compiled dwarf symbols is _ZNKSs5c_strEv, Clang also generates the same symbol. The call to m_decl_map->GetFunctionAddress is failing because the mangled name that is being generated by the JIT compiled expression is actually the fully specified name, _ZNKSbIcSt17char_traits<char>St15allocator<char>E5c_strEv, which is equivalent to basic_string<char,char_traits<char>,allocator<char>>.
I have been walking through the expression parsing code but have not been able to locate where this name is actually generated. I am guessing the name is generated during the ParseAST but I have not been able to track it down yet, any help would be appreciated.

- Alex

Alex,

the expression parser works roughly as follows (in the case of JIT execution, anyway):

  • you type in some code;
  • we wrap it up so that it looks like a translation unit to Clang (i.e., no bare code);
  • we send it to Clang to produce an IR module, and Clang asks the ClangExpressionDeclMap/ClangASTSource for all the variables and types in the program;
  • we prepare that IR module for execution with IRForTarget; and
  • the JIT produces binary code which we can run.

The IR module that the Clang parser produces already contains all of the external function references like _ZNKSbIcSt17char_traitsSt15allocatorE5c_strEv. LLDB is not responsible for generating these; that is Clang’s job.

One immediate problem I see with this symbol is that it is a mangled name with angle brackets (<>) in it. I don’t believe this is proper mangling.

What I think is happening here is that the debug information is telling you that the type of something is char_traits but treating that as a normal type instead of a templated type. Then we’ll report a normal type with a name containing angle brackets to Clang, and it’ll produce bogus mangled names as you see.

One way you can see what types are being reported for things is by enabling the expression log:

(lldb) log enable -f /tmp/lldb.expr.log.txt lldb expr
(lldb) expr your expression

That should tell you what types we reported (and what IR we got). You’ll want to be very familiar with this log to fix bugs in the expression parser.

Good luck and let me know if you have any more questions.

Sean

One immediate problem I see with this symbol is that it is a mangled name with angle brackets (<>) in it. I don’t believe this is proper mangling.

What I think is happening here is that the debug information is telling you that the type of something is char_traits but treating that as a normal type instead of a templated type. Then we’ll report a normal type with a name containing angle brackets to Clang, and it’ll produce bogus mangled names as you see.

This is what I see happening in the clang mangling code. In the clang AST parsing when it attempts to do the mangled name substitution it is failing when checking to see if it is a basic_string<char,char_traits,allocator>. It is failing when checking to see if char_traits is a char specialization of char_traits. In this check if fails the dyn_cast to ClassTemplateSpecializationDecl which indicates to me that is doesn’t think it is a specialization of a template class.

One way you can see what types are being reported for things is by enabling the expression log:

(lldb) log enable -f /tmp/lldb.expr.log.txt lldb expr
(lldb) expr your expression

I will take a look at the logs, and thanks for the pointers.

  • Alex