Hi Sean, I've been reading through source/Expression and really like the way it's constructed - very readable and lots of nifty insights. What got me onto this tome was a Linux-specific test failure in expression evaluation that uses a call to strlen.
For instance, lang/c/strings fails with a garbage return value on Linux when
evaluating the following source:
void
$__lldb_expr(void *$__lldb_arg)
{
(int)strlen("hello");
}
Interestingly, expr (int)printf("hello") does just fine. In both cases,
FindExternalVisibleDecls uses the Symtab plugin to lookup the address, and the
result is analogous.
static <unknown type> strlen(...)
static <unknown type> printf(...)
In fact, looking at the log generated by "log enable lldb expr", I found no
differences that suggest a different code path. In fact, the assembly is
identical (except for the address in %rcx used as an argument to callq). I
played around with setting a default LanguageType of C++ rather than ObjC++,
but other than the metadata, I saw no changes in the resulting assembly (which
makes sense since it's fundamentally C code and the same ABI).
At first I wondered if printf succeeded because it accepts varargs, but I find
that strcoll("hello", "hell") is also evaluated correctly. Looking at return
types, argument lists, and function attributes (i.e. nounwind and readonly),
the difference between the calls that succeed and those that fail on Linux is
the return type. For instance, strcspn("hello", "hell") also fails with a
bogus result. This occurs even if the cast is long as in
(long)strlen("hello"). However, adding a function to main.c allows me to
evaluate:
size_t do_test(const char *data) {
return strlen(data);
}
expr (int)do_test("hello")
expr (long)do_test("hello")
expr (size_t)do_test("hello")
In the above case, DWARF is available, so the log is quite different.
Incidentally, size_t isn't a valid cast on OS/X, but it's equivalent to long on
64-bit Linux with ObjC++ or C++. So, this could be a rough edge. Note that
the problem does not reproduce on Mac OS/X. I attached the logs on Linux and
OS/X, and again there is no difference in the resulting assembly or the
dematerialization except for the bogus result. The logs were prepared against
r169556 of lldb.
I'm starting to suspect that there is an error of omission somewhere. For
instance, llvm.org/demo generates a declare statement for strlen that includes
attributes that lldb does not generate:
declare i64 @strlen(i8*) nounwind readonly
Any thoughts are certainly welcome,
- Ashok
strlen-linux.log
Description: strlen-linux.log
strlen-mac.log
Description: strlen-mac.log
_______________________________________________ lldb-dev mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
