[lldb-dev] Trying to understand how Expression Evaluation works

Jim Ingham via lldb-dev lldb-dev at lists.llvm.org
Wed Jul 20 16:58:05 PDT 2016


> On Jul 20, 2016, at 4:32 PM, Khaled Mohammed via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> 
> Hi,
> 
> Is there a document which describes in detail how the expression evaluation works? is there a wiki for lldb developers?
> 

There is no documentation beyond the code & its comments describing how this is done, but you can get a fair bit of insight if you turn on the expression log:

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

then run an expression and go read through the log.  It's pretty voluminous, but fairly clear, and there are generally Headers in the log text that can be found directly in the "log->Printf" calls in the sources, so you can trace where in the code each bit of work happens by searching for them.

> Few questions...
> 1) Does it use clang to parse the expression text directly? or is the expression text morphed into a function before passing to clang?

The latter.  The expression log will show the transformed text fairly early on in the log in the log.  The function is different depending on the context we're trying to emulate (C++ or ObjC method, for instance.)  Sean recently added the ability to parse "top-level code" (with "expr --top-level --")  in which case the code doesn't get wrapped.

> 2) Is the evaluation done in target or in the host?

If it can be IR interpreted (pretty much if there are no function calls) it is interpreted in the host, but side effects will be propagated to the target.

If it can't be IR interpreted, it will be JIT'ed and run in the target.  We don't have a hybrid mode like gdb where we interpret the results of the parse, but stop along the way to dispatch any function calls by hand to the target.  Doing it that way forces gdb to know all the ABI details.  The lldb wrapper function is simple (taking one pointer, and returns nothing.)  So that's the only bit of the ABI we have to get right for expression evaluations to work.  clang, which has to get this right anyway, takes care of the rest.

LLDB does have another way to run code: "UtilityFunction" which takes more than one argument, and calls an extant function in the target directly.  That part doesn't use clang, and really only supports passing it a few scalars, and returning a scalar.

> 3) Is the code generation done in host or target? if code generation is done in the host, how is binary passed to the target to execute?

Code generation is done on the host using a version of the clang library built into lldb.

The JIT'ed code is written directly into memory lldb allocates in the target, and executed from there.  The LLVM JIT can be told the addresses of the sections as they will be in the target, so it can fix up any internal references for the target location.  You can also see this stage happen in the log.

Hope this helps,

Jim


> 
> Thanks,
> -Khaled
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev



More information about the lldb-dev mailing list