<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Sourabh,<div class=""><br class=""></div><div class="">Thanks for raising this issue. To answer your question, (afaik) there isn’t anyone working on <font face="Calibri, sans-serif" class=""><span style="font-size: 11pt;" class="">DW_AT_start_scope support in tree. We</span><span style="font-size: 14.666666984558105px;" class="">’</span><span style="font-size: 11pt;" class="">re looking for a solution to this problem for Swift debugging, where it's important not to make a debug location for a variable available until its (guaranteed) initialization is complete.</span></font></div><div class=""><span style="font-family: Calibri, sans-serif; font-size: 11pt;" class=""><br class=""></span></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class="">If at all possible, I’d /much/ rather we use the existing location list machinery to solve this problem. Fundamentally, we’re looking for a way to express when a location for a variable becomes available, and location lists give us that already.</span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class=""><br class=""></span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class="">To test this out, I took the IR for your test case, replaced all calls to “dbg.declare(…)” with “dbg.value(…, DW_OP_deref)”, and compiled with `-g -O0 -mllvm -fast-isel=false` (apparently FastISel doesn’t know what to do with frame-index dbg.values, but this is simple to fix). This seemed to work pretty well, and the DWARF looked legit:</span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class=""><br class=""></span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class="">```</span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class="">0x0000005f: DW_TAG_variable</span><br class=""><span style="font-size: 14.666666984558105px;" class=""> DW_AT_location (DW_OP_fbreg -20)</span><br class=""><span style="font-size: 14.666666984558105px;" class=""> DW_AT_name ("Local")</span><br class=""><br class=""><span style="font-size: 14.666666984558105px;" class="">0x0000006d: DW_TAG_lexical_block</span><br class=""><span style="font-size: 14.666666984558105px;" class=""> DW_AT_low_pc (0x0000000100000f4f)</span><br class=""><span style="font-size: 14.666666984558105px;" class=""> DW_AT_high_pc (0x0000000100000f84)</span><br class=""><br class=""><span style="font-size: 14.666666984558105px;" class="">0x0000007a: DW_TAG_variable</span><br class=""><span style="font-size: 14.666666984558105px;" class=""> DW_AT_location (0x00000000</span><br class=""><span style="font-size: 14.666666984558105px;" class=""> [0x0000000100000f63, 0x0000000100000f8c): DW_OP_breg6 RBP-24)</span><br class=""><span style="font-size: 14.666666984558105px;" class=""> DW_AT_name ("Local”)</span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class="">```<br class=""><br class=""></span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class="">I did find one lldb bug where it didn’t know to look up a variable in the parent scope when stopped at your second printf() call (line 6). But that's a general bug: we’d have to fix it even if we used DW_AT_start_scope.</span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class=""><br class=""></span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class="">The upshot of sticking to location lists is that fixing any bugs we find improves optimized debugging workflows. And Swift -Onone debugging workflows as well, since Swift runs certain mandatory optimizations which can make the DWARF at -Onone fairly complex.</span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class=""><br class=""></span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class="">best,</span></font></div><div class=""><font face="Calibri, sans-serif" class=""><span style="font-size: 14.666666984558105px;" class="">vedant</span></font></div><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Apr 15, 2020, at 9:53 AM, David Blaikie via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">As always, concerned about the size growth in object files this might produce - though looks like the DWARF spec avoids the worst of this in unoptimized code by using an offset relative to the start of the enclosing scope, so it doesn't require a relocation in that case.<br class=""><br class="">I have no idea what the LLVM DWARF representation for this would look like - short of making even more fine-grained scopes in the DILexicalScope hierarchy, which sounds really expensive from a memory perspective. That's really where I worry that the cost to this feature might outweigh the benefit (& might be why no one's done this in the past) - but data should tell us that. As much as in-tree development is preferred, this might be the sort of thing worth prototyping out of tree first to see if it can be made viable before adding the complexity to the LLVM project proper - but I'm open to ideas/suggestions.</div><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 15, 2020 at 3:15 AM Sourabh Singh Tomar <<a href="mailto:sourav0311@gmail.com" class="">sourav0311@gmail.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class=""><div class=""><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Hello Everyone,</div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">I need to have your thoughts on this.</div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Consider the following test case --</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">-------------------------------------------</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> 1 int main(int Argc, char **Argv) {<br class="">
2 int Local = 6;<br class="">
3 printf("%d\n",Local);<br class="">
4<br class="">
5 {<br class="">
6 printf("%d\n",Local);<br class="">
7 int Local = 7;<br class="">
8 printf("%d\n",Local);<br class="">
9 }<br class="">
10<br class="">
11 return 0;<br class="">
12 }</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">--------------------------------------------</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">When compiled in debug mode with compilers including (trunk
gcc and trunk clang) and debugging with GDB at Line No.6, the following
behavior is observed</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Breakpoint 1, main (Argc=1, Argv=0x7fffffffe458) at
MainScope.c:6<br class="">
6
printf("%d\n",Local);<br class="">
(gdb) print Local<br class="">
$1 = 2102704 -- some Garbage value, </div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">(gdb) info addr Local<br class="">
Symbol "Local" is a variable at frame base reg $rbp offset
0+-24. -- <i class="">This is location of *Local* declared inside scope, but
as you may notice that the variable being referred here is from the outer
scope.</i></div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">This problem persists with both GDB and LLDB. Since we have
entered the Lexical Scope and when we try to print value of *Local*, it
will look into the *current scope* and fetch the value if the variable exists
in scope(in case variable doesn't exist, GDB searches for it in the outer
scope). </div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">This is regardless of whether the variable has actually came
into scope(or actually defined) at Line No. 7. Since DWARF already defined the
location(on stack) which will be valid for the lifetime of the variable, contrary
to when the variable is actually defined(or allocated) which is in this case
Line No. 7.</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">---------------------------------------------</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> 0x0000006d: DW_TAG_lexical_block<br class="">
DW_AT_low_pc
(0x00000000002016d1)<br class="">
DW_AT_high_pc
(0x000000000020170b) </div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">0x0000007a: DW_TAG_variable<br class="">
DW_AT_location (DW_OP_fbreg -24)<br class="">
DW_AT_name ("Local")<br class="">
DW_AT_decl_file ("MainScope.c")<br class="">
DW_AT_decl_line (7)<br class="">
DW_AT_type (0x0000008a "int")</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">----------------------------------------------</div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">The DWARF specification provides the DW_AT_start_scope
attribute to deal with this issue (Sec 3.9 Declarations with Reduced Scope
DWARFv5). This attribute aims at limiting the scope of variables within the
lexical scope in which it is defined to from where it has been declared/
defined.</div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">In order to fix this issue, we want to modify llvm so that DW_AT_start_scope
is emitted for the variable in the inner block (in the above example). This
limits the scope of the inner block variable to start from the point of its
declaration. </div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">For POC, we inserted DW_AT_start_scope in this inner *Local* variable, resultant dwarf after this.</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">-----------------------------</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">0x0000006d: DW_TAG_lexical_block<br class="">
DW_AT_low_pc
(0x00000000002016d1)<br class="">
DW_AT_high_pc
(0x000000000020170b)</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">0x0000007a: DW_TAG_variable<br class=""> <b class=""><i class=""> DW_AT_start_scope (0x17) -- restricted within a subset(starting from the
point of definition(specified as an offset)) of entire ranges covered by Lex Block.</i></b><br class="">
DW_AT_location (DW_OP_fbreg -24)<br class="">
DW_AT_name ("Local")<br class="">
DW_AT_decl_file ("MainScope.c")<br class="">
DW_AT_decl_line (7)<br class="">
DW_AT_type (0x00000092 "int")</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">----------------------------</div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">We also modified ‘gdb’ to interpret DW_AT_start_scope so
that the scope of the variable is limited from the PC where the value of
DW_AT_start_scope is. If the debugger is stopped at a point within the same
lexical block but at a PC before DW_AT_start_scope, then gdb follows the normal
search mechanism of searching in consecutive super blocks till it gets a match
or it reaches the global block. After the modification, GDB is able to correctly show the value *6* in
our example.</div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">After incorporating changes --</div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> Breakpoint 1, main (Argc=1, Argv=0x7fffffffe458) at
MainScope.c:6<br class="">
6
printf("%d\n",Local);<br class="">
(gdb) print Local<br class=""><b class=""><i class="">
$1 = 6 --- Value retrieved from outer scope</i></b></div><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">(gdb)
info addr Local</div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
</p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Symbol
"Local" is a variable at frame base reg $rbp offset 0+-20.</div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Could you guys please let us know your thoughts or suggestions
on this? Was/ Is there is an existing effort already going on to deal with this
problem? </div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"> </p>
<span style="font-size:11pt;font-family:Calibri,sans-serif" class="">Even though location lists can be used to deal
with this scenario, in my experience, location lists are emitted at higher
optimization levels, and with the usage of location lists in this example, gdb
prints out <optimized out> (as expected) if it is stopped at a PC in the
same lexical block but before the point of declaration of the local variable.</span> <br class=""></div><div class=""><br class=""></div><div class="">Thank You,<br class="">Sourabh Singh Tomar.</div></div>
</blockquote></div>
_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><br class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<br class=""></div></blockquote></div><br class=""></div></body></html>