<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 12 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0in;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Courier New";}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:"Courier New";}
span.llvmkeyword
{mso-style-name:llvm_keyword;}
span.llvmtype
{mso-style-name:llvm_type;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:411245062;
mso-list-type:hybrid;
mso-list-template-ids:1222573236 -1582118112 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l0:level1
{mso-level-start-at:0;
mso-level-number-format:bullet;
mso-level-text:-;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Calibri","sans-serif";
mso-fareast-font-family:Calibri;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Hi Sean,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">For instance, lang/c/strings fails with a garbage return value on Linux when evaluating the following source:<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in;text-autospace:none"><span style="font-family:"Courier New"">void<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;text-autospace:none"><span style="font-family:"Courier New"">$__lldb_expr(void *$__lldb_arg)<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;text-autospace:none"><span style="font-family:"Courier New"">{<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;text-autospace:none"><span style="font-family:"Courier New""> (int)strlen("hello");<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;text-autospace:none"><span style="font-family:"Courier New"">}<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal">Interestingly, <i>expr (int)printf(“hello”)</i> does just fine. In both cases, FindExternalVisibleDecls uses the Symtab plugin to lookup the address, and the result is analogous.<o:p></o:p></p>
<p class="MsoNormal"> static <unknown type> strlen(...) <o:p></o:p></p>
<p class="MsoNormal"> static <unknown type> printf(...) <o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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).<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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:<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in">size_t do_test(const char *data) {<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"> return strlen(data);<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in">}<o:p></o:p></p>
<p class="MsoNormal" style="text-indent:.5in">expr (int)do_test(“hello”)<o:p></o:p></p>
<p class="MsoNormal" style="text-indent:.5in">expr (long)do_test(“hello”)<o:p></o:p></p>
<p class="MsoNormal" style="text-indent:.5in">expr (size_t)do_test(“hello”)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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:<o:p></o:p></p>
<pre style="margin-left:.5in"><b><span style="color:blue">declare</span></b><span style="color:black"> </span><i><span style="color:green">i64</span></i><span style="color:black"> @strlen(</span><i><span style="color:green">i8</span></i><span style="color:black">*) </span><b><span style="color:blue">nounwind</span></b><span style="color:black"> </span><b><span style="color:blue">readonly</span></b><span style="color:black"><o:p></o:p></span></pre>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Any thoughts are certainly welcome,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoListParagraph" style="text-indent:-.25in;mso-list:l0 level1 lfo1"><![if !supportLists]><span style="mso-list:Ignore">-<span style="font:7.0pt "Times New Roman"">
</span></span><![endif]>Ashok<span style="font-family:"Courier New""><o:p></o:p></span></p>
</div>
</body>
</html>