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

Attachment: strlen-linux.log
Description: strlen-linux.log

Attachment: strlen-mac.log
Description: strlen-mac.log

_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to