-
Notifications
You must be signed in to change notification settings - Fork 12.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[lldb][DWARF] Delay struct/class/union definition DIE searching when …
…parsing declaration DIEs. (#90663) This is the implementation for https://discourse.llvm.org/t/rfc-delay-definition-die-searching-when-parse-a-declaration-die-for-record-type/78526. #### Motivation Currently, lldb eagerly searches for definition DIE when parsing a declaration DIE for struct/class/union definition DIE. It will search for all definition DIEs with the same unqualified name (just `DW_AT_name` ) and then find out those DIEs with same fully qualified name. Then lldb will try to resolve those DIEs to create the Types from definition DIEs. It works fine most time. However, when built with `-gsimple-template-names`, the search graph expands very quickly, because for the specialized-template classes, they don’t have template parameter names encoded inside `DW_AT_name`. They have `DW_TAG_template_type_parameter` to reference the types used as template parameters. In order to identify if a definition DIE matches a declaration DIE, lldb needs to resolve all template parameter types first and those template parameter types might be template classes as well, and so on… So, the search graph explodes, causing a lot unnecessary searching/type-resolving to just get the fully qualified names for a specialized-template class. This causes lldb stack overflow for us internally on template-heavy libraries. #### Implementation Instead of searching for definition DIEs when parsing declaration DIEs, we always construct the record type from the DIE regardless if it's definition or declaration. The process of searching for definition DIE is refactored to `DWARFASTParserClang::FindDefinitionTypeForDIE` which is invoked when 1) completing the type on `SymbolFileDWARF::CompleteType`. 2) the record type needs to start its definition as a containing type so that nested classes can be added into it in `PrepareContextToReceiveMembers`. The key difference is `SymbolFileDWARF::ResolveType` return a `Type*` that might be created from declaration DIE, which means it hasn't starts its definition yet. We also need to change according in places where we want the type to start definition, like `PrepareContextToReceiveMembers` (I'm not aware of any other places, but this should be a simple call to `SymbolFileDWARF::FindDefinitionDIE`) #### Result It fixes the stack overflow of lldb for the internal binary built with simple template name. When constructing the fully qualified name built with `-gsimple-template-names`, it gets the name of the type parameter by resolving the referenced DIE, which might be a declaration (we won't try to search for the definition DIE to just get the name). I got rough measurement about the time using the same commands (set breakpoint, run, expr this, exit). For the binary built without `-gsimple-template-names`, this change has no impact on time, still taking 41 seconds to complete. When built with `-gsimple-template-names`, it also takes about 41 seconds to complete wit this change.
- Loading branch information
Showing
8 changed files
with
438 additions
and
383 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
397 changes: 218 additions & 179 deletions
397
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Large diffs are not rendered by default.
Oops, something went wrong.
197 changes: 88 additions & 109 deletions
197
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
lldb/test/Shell/SymbolFile/DWARF/delayed-definition-die-searching.test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Test definition DIE searching is delayed until complete type is required. | ||
|
||
# RUN: split-file %s %t | ||
# RUN: %clangxx_host %t/main.cpp %t/t1_def.cpp -g -o %t.out | ||
# RUN: %lldb -b %t.out -s %t/lldb.cmd | FileCheck %s | ||
|
||
# CHECK: (lldb) p v1 | ||
# CHECK: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't2<t1>' | ||
# CHECK: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't1' | ||
# CHECK: DW_TAG_structure_type (DW_TAG_structure_type) 't2<t1>' resolving forward declaration... | ||
# CHECK: (t2<t1>) {} | ||
# CHECK: (lldb) p v2 | ||
# CHECK: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't1' | ||
# CHECK: DW_TAG_structure_type (DW_TAG_structure_type) 't1' resolving forward declaration... | ||
|
||
#--- lldb.cmd | ||
log enable dwarf comp | ||
p v1 | ||
p v2 | ||
|
||
#--- main.cpp | ||
template<typename T> | ||
struct t2 { | ||
}; | ||
struct t1; | ||
t2<t1> v1; // this CU doesn't have definition DIE for t1, but only declaration DIE for it. | ||
int main() { | ||
} | ||
|
||
#--- t1_def.cpp | ||
struct t1 { // this CU contains definition DIE for t1. | ||
int x; | ||
}; | ||
t1 v2; |