<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 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"MS Mincho";
        panose-1:2 2 6 9 4 2 5 8 3 4;}
@font-face
        {font-family:"MS Mincho";
        panose-1:2 2 6 9 4 2 5 8 3 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@MS Mincho";
        panose-1:2 2 6 9 4 2 5 8 3 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;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></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"><o:p> </o:p></p>
<p class="MsoNormal">Hi,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I've encountered a situation where Clang generates an incorrect location list for the variable. GDB chokes on it, but LLDB understands it.<o:p></o:p></p>
<p class="MsoNormal">DWARF standard doesn't say that this location list is legal. Is it a bug in Clang that got compensated by LLDB? Or is it done on purpose?<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Here is more information.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Consider the following test:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">---main.cpp---<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">#include "stuff.h"<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">int main()<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">                int c = 0;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">                for (int a = 0; a < 100; ++a)<o:p></o:p></p>
<p class="MsoNormal">                                c += func(a);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">                return c;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">--- stuff.h---<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">extern int func(int a);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">---stuff.cpp---<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">#include "stuff.h"<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">int func(int a)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">        return a * 15;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The following DWARF is generated for variables "a" and "c":<o:p></o:p></p>
<p class="MsoNormal"><2><43>: Abbrev Number: 3 (DW_TAG_variable)<o:p></o:p></p>
<p class="MsoNormal">    <44>   DW_AT_location    : 0x0      (location list)<o:p></o:p></p>
<p class="MsoNormal">    <48>   DW_AT_name        : (indirect string, offset: 0x73): c<o:p></o:p></p>
<p class="MsoNormal">    <4c>   DW_AT_decl_file   : 1<o:p></o:p></p>
<p class="MsoNormal">    <4d>   DW_AT_decl_line   : 5<o:p></o:p></p>
<p class="MsoNormal">    <4e>   DW_AT_type        : <0x70><o:p></o:p></p>
<p class="MsoNormal"><2><52>: Abbrev Number: 4 (DW_TAG_lexical_block)<o:p></o:p></p>
<p class="MsoNormal">    <53>   DW_AT_low_pc      : 0x12<o:p></o:p></p>
<p class="MsoNormal">    <5b>   DW_AT_high_pc     : 0x10<o:p></o:p></p>
<p class="MsoNormal"><3><5f>: Abbrev Number: 3 (DW_TAG_variable)<o:p></o:p></p>
<p class="MsoNormal">    <60>   DW_AT_location    : 0x39     (location list)<o:p></o:p></p>
<p class="MsoNormal">    <64>   DW_AT_name        : (indirect string, offset: 0x75): a<o:p></o:p></p>
<p class="MsoNormal">    <68>   DW_AT_decl_file   : 1<o:p></o:p></p>
<p class="MsoNormal">    <69>   DW_AT_decl_line   : 7<o:p></o:p></p>
<p class="MsoNormal">    <6a>   DW_AT_type        : <0x70><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Content of the .debug_loc section:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    Offset   Begin    End      Expression<o:p></o:p></p>
<p class="MsoNormal">    00000000 0000000000000003 0000000000000026 (DW_OP_consts: 13)<o:p></o:p></p>
<p class="MsoNormal">    00000014 0000000000000026 0000000000000029 (DW_OP_reg0 (rax); DW_OP_piece: 4)<o:p></o:p></p>
<p class="MsoNormal">    00000029 <End of list><o:p></o:p></p>
<p class="MsoNormal">    00000039 0000000000000008 000000000000001d (DW_OP_consts: 0)<o:p></o:p></p>
<p class="MsoNormal">    0000004d 000000000000001d 0000000000000022 (DW_OP_reg3 (rbx); DW_OP_piece: 4)<o:p></o:p></p>
<p class="MsoNormal">    00000062 <End of list><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">DWARF expressions"DW_OP_consts 13" and "DW_OP_consts 0" are legal, but are they legal as locations? I've checked DWARF-3, DWAWF-4 and DWARF-5<o:p></o:p></p>
<p class="MsoNormal">and it seems that the proper way to describe the situation where in a specific address range the value is constant is "DW_OP_constu 0, DW_OP_stack_value".<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">DW_OP_const pushes a value on to the expression stack, this describes a location, not a value. In order for the stack to represent a value the expression needs to end with DW_OP_stack_value.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">GDB thinks that "DW_OP_consts 0" represents a location in memory:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Breakpoint 1, main () at main.cpp:8<o:p></o:p></p>
<p class="MsoNormal">8                       c += func(a);<o:p></o:p></p>
<p class="MsoNormal">(gdb) p c<o:p></o:p></p>
<p class="MsoNormal">Cannot access memory at address 0xd<o:p></o:p></p>
<p class="MsoNormal">(gdb) p a<o:p></o:p></p>
<p class="MsoNormal">Cannot access memory at address 0x0<o:p></o:p></p>
<p class="MsoNormal">(gdb)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">LLDB seems to know how to interpret DW_OP_consts correctly.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">(lldb) run<o:p></o:p></p>
<p class="MsoNormal">Process 8216 launching<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">* thread #1: tid = 8216, 0x0000000000400502 main.O2.exe`main + 18 at main.cpp:8, name =<o:p></o:p></p>
<p class="MsoNormal">'main.O2.exe', stop reason = breakpoint 1.1<o:p></o:p></p>
<p class="MsoNormal">    frame #0: 0x0000000000400502 main.O2.exe`main + 18 at main.cpp:8<o:p></o:p></p>
<p class="MsoNormal">   5            int c = 13;<o:p></o:p></p>
<p class="MsoNormal">   6<o:p></o:p></p>
<p class="MsoNormal">   7            for (int a = 0; a < 100; ++a)<o:p></o:p></p>
<p class="MsoNormal">-> 8                    c += func(a);<o:p></o:p></p>
<p class="MsoNormal">   9<o:p></o:p></p>
<p class="MsoNormal">   10           return c;<o:p></o:p></p>
<p class="MsoNormal">   11   }<o:p></o:p></p>
<p class="MsoNormal">(lldb) p c<o:p></o:p></p>
<p class="MsoNormal">(int) $0 = 13<o:p></o:p></p>
<p class="MsoNormal">(lldb) p a<o:p></o:p></p>
<p class="MsoNormal">(int) $1 = 0<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Is this implemented in Clang on purpose for some reason? Or is it a bug in Clang that gets compensated by the debugger?<o:p></o:p></p>
<p class="MsoNormal">Thanks!<o:p></o:p></p>
<p class="MsoNormal">Katya.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>