[AMD Official Use Only - Internal Distribution Only] Hello Everyone,
I need to have your thoughts on this. Consider the following test case -- ------------------------------------------- 1 int main(int Argc, char **Argv) { 2 int Local = 6; 3 printf("%d\n",Local); 4 5 { 6 printf("%d\n",Local); 7 int Local = 7; 8 printf("%d\n",Local); 9 } 10 11 return 0; 12 } -------------------------------------------- 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 Breakpoint 1, main (Argc=1, Argv=0x7fffffffe458) at MainScope.c:6 6 printf("%d\n",Local); (gdb) print Local $1 = 2102704 -- some Garbage value, (gdb) info addr Local Symbol "Local" is a variable at frame base reg $rbp offset 0+-24. -- This is location of *Local* declared inside scope, but as you may notice that the variable being referred here is from the outer scope. 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). 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. --------------------------------------------- 0x0000006d: DW_TAG_lexical_block DW_AT_low_pc (0x00000000002016d1) DW_AT_high_pc (0x000000000020170b) 0x0000007a: DW_TAG_variable DW_AT_location (DW_OP_fbreg -24) DW_AT_name ("Local") DW_AT_decl_file ("MainScope.c") DW_AT_decl_line (7) DW_AT_type (0x0000008a "int") ---------------------------------------------- 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. 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. For POC, we inserted DW_AT_start_scope in this inner *Local* variable, resultant dwarf after this. ----------------------------- 0x0000006d: DW_TAG_lexical_block DW_AT_low_pc (0x00000000002016d1) DW_AT_high_pc (0x000000000020170b) 0x0000007a: DW_TAG_variable 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. DW_AT_location (DW_OP_fbreg -24) DW_AT_name ("Local") DW_AT_decl_file ("MainScope.c") DW_AT_decl_line (7) DW_AT_type (0x00000092 "int") ---------------------------- 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. After incorporating changes -- Breakpoint 1, main (Argc=1, Argv=0x7fffffffe458) at MainScope.c:6 6 printf("%d\n",Local); (gdb) print Local $1 = 6 --- Value retrieved from outer scope (gdb) info addr Local Symbol "Local" is a variable at frame base reg $rbp offset 0+-20. 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? 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. Thank You, Sourabh Singh Tomar.