[Lldb-commits] [PATCH] D110571: [lldb] Add omitted abstract formal parameters in DWARF symbol files
Jaroslav Sevcik via Phabricator via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 29 23:21:54 PDT 2021
jarin added a comment.
In D110571#3031846 <https://reviews.llvm.org/D110571#3031846>, @clayborg wrote:
> In D110571#3031140 <https://reviews.llvm.org/D110571#3031140>, @jarin wrote:
>
>> For illustration:
>>
>> 0x100 DW_TAG_subprogram
>> DW_AT_name "inlined_function"
>> ... no DW_AT_low_pc here ...
>> 0x110 DW_TAG_formal_parameter
>> DW_AT_name "unused"
>> ...
>> ...
>> 0x200 DW_TAG_subprogram
>> DW_AT_name ("top_level_function_with_address"
>> DW_AT_low_pc (0x3000)
>> DW_AT_high_pc (0x3100)
>> ...
>> 0x210 DW_TAG_inlined_subroutine
>> DW_AT_abstract_origin (0x100 "inlined_function")
>> DW_AT_low_pc (0x3010)
>> DW_AT_high_pc (0x3020)
>> # Note the missing DW_TAG_formal_parameter here!
>> NULL
>> ...
>> 0x400 DW_TAG_subprogram
>> DW_AT_name ("another_top_level_function_with_address"
>> DW_AT_low_pc (0x5000)
>> DW_AT_high_pc (0x5100)
>> ...
>> 0x410 DW_TAG_inlined_subroutine
>> DW_AT_abstract_origin (0x100 "inlined_function")
>> DW_AT_low_pc (0x5030)
>> DW_AT_high_pc (0x5040)
>> # Note the missing DW_TAG_formal_parameter here!
>> NULL
>> ...
>>
>> Here, we will create just one variable for the formal parameter "unused" (DIE offset 0x110). That variable's symbol context will be randomly one of the DW_TAG_inline subroutine blocks (either 0x210 or 0x410), and the variable will be inserted into two variable lists, one for the Block associated with the DIE at 0x210 and one for DIE associated with 0x410.
>
> I hear what you are saying, but I am not sure this will be happening. Let me explain: for each concrete DW_TAG_subprogram (0x200 and 0x400 in your example above), we create a unique lldb_private::Function object whose UserID will be 0x200 for "top_level_function_with_address" and 0x400 for "another_top_level_function_with_address". Each of those functions might be asked for their lldb_private::Block objects at some point and we should create unique lldb_private::Block for each DW_TAG_lexical_block and DW_TAG_inlined_subroutine that is contained within these unique DIEs. Each of these should now have a variable within the block that is a parameter whose name is "unused" and whose symbol context should be 0x210 for the 0x200 DIE, and 0x410 for the 0x400 DIE. So it would be great to make sure this happens correctly. From looking at the code, it seems like this should be happening correctly, but you might know better since you made these new modifications.
Hi Greg, thanks for the detailed description! What you say is indeed happening until the point "Each of these [blocks] should now have a variable within the block that is a parameter whose name is "unused" and whose symbol context should be 0x210 for the 0x200 DIE, and 0x410 for the 0x400 DIE.".
With my patch, LLDB creates only one variable here, its symbol context will be whichever block was parsed first and that variable will be inserted into the variable lists of blocks corresponding to 0x210 and 0x410. The reason why LLDB creates only one variable is that there is a cache of variables indexed by DIEs. When we call ParseVariableDIE <https://github.com/llvm/llvm-project/blob/941191aae4abaf88b176bec8cfe1c841a5832642/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp#L3087> first time for the variable "unused" (DIE 0x110) and symbol context 0x210, the variable gets created <https://github.com/llvm/llvm-project/blob/941191aae4abaf88b176bec8cfe1c841a5832642/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp#L3417> and inserted <https://github.com/llvm/llvm-project/blob/941191aae4abaf88b176bec8cfe1c841a5832642/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp#L3431> under the key 0x110. When we call ParseVariableDIE second time for "unused" (still 0x110) and symbol context 0x410, we will find and return <https://github.com/llvm/llvm-project/blob/941191aae4abaf88b176bec8cfe1c841a5832642/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp#L3097> the originally created variable (with symbol context 0x210!) and happily insert it into the block for 0x410.
>From what you say, this is not the desired behavior? If we wanted two instances of the variable (one for each block), we could change the DIE-to-variable cache <https://github.com/llvm/llvm-project/blob/47d66355ef9039a15b7265945e3deb331d7f9e05/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h#L324> to be indexed by a pair <symbol-context-DIE, variable-DIE>.
I have validated this with a simple example below, after adding printing of the variable address (var_sp.get()) at its creation point <https://github.com/llvm/llvm-project/blob/941191aae4abaf88b176bec8cfe1c841a5832642/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp#L3417> and printing of variable address (var_sp.get()) and list address (this) at variable list addition <https://github.com/llvm/llvm-project/blob/1f0bc617bdd11a4f3b0d820603b0089f81aca79b/lldb/source/Symbol/VariableList.cpp#L29>. Below is the code and the session log of lldb (with this patch applied).
Code (compiled with a recent clang with `-O1 -g`):
#include <stdio.h>
__attribute__((always_inline))
void f(int unused) {
printf("Hello");
}
__attribute__((noinline))
void other() {
f(1);
}
int main() {
f(2);
other();
return 0;
}
The lldb session (some fluff replaced with `...`):
$ bin/lldb a.out
...
(lldb) b f
...
(lldb) r
...
Created var 'unused' 0x7f6c48004f60 from DIE 0x4f ### 0x4f is the formal_parameter from the abstract |f|
Adding variable 0x7f6c48004f60 to the list 0x7f6c48004910 ### Inserting into the inlined block in |main|
Adding variable 0x7f6c48004f60 to the list 0x7f6c4f0a4a70 ### Ignore, this is the output list for formatting
Process ... stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.3
frame #0: 0x0000000000401151 a.out`main [inlined] f(unused=<unavailable>) at a.cc:5:3
...
(lldb) c
...
Adding variable 0x7f6c48004f60 to the list 0x7f6c4804b250 ### Inserting the same var into the block for |other|
Adding variable 0x7f6c48004f60 to the list 0x7f6c4f0a4a70
Process ... stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.2
frame #0: 0x0000000000401141 a.out`other() [inlined] f(unused=<unavailable>) at a.cc:5:3
...
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D110571/new/
https://reviews.llvm.org/D110571
More information about the lldb-commits
mailing list