tonkosi created this revision. tonkosi added reviewers: werat, teemperor. tonkosi requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
LLDB uses mangled name to construct a fully qualified name for global variables. Sometimes DW_TAG_linkage_name attribute is missing from debug info, so LLDB has to rely on parent entries to construct the fully qualified name. Currently, the fallback is handled when the parent DW_TAG is either DW_TAG_compiled_unit or DW_TAG_partial_unit, which may not work well for global constants in namespaces. For example: namespace ns { const int x = 10; } may produce the following debug info: <1><2a>: Abbrev Number: 2 (DW_TAG_namespace) <2b> DW_AT_name : (indirect string, offset: 0x5e): ns <2><2f>: Abbrev Number: 3 (DW_TAG_variable) <30> DW_AT_name : (indirect string, offset: 0x61): x <34> DW_AT_type : <0x3c> <38> DW_AT_decl_file : 1 <39> DW_AT_decl_line : 2 <3a> DW_AT_const_value : 10 Since the fallback didn't handle the case when parent tag is DW_TAG_namespace, LLDB wasn't able to match the variable by its fully qualified name "ns::x". This change fixes this by additional check if the parent is a DW_TAG_namespace. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D112147 Files: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/test/API/lang/cpp/global_variables/TestCPPGlobalVariables.py lldb/test/API/lang/cpp/global_variables/main.cpp Index: lldb/test/API/lang/cpp/global_variables/main.cpp =================================================================== --- lldb/test/API/lang/cpp/global_variables/main.cpp +++ lldb/test/API/lang/cpp/global_variables/main.cpp @@ -1,10 +1,12 @@ #include <stdio.h> namespace abc { - int g_file_global_int = 42; +int g_file_global_int = 42; +const int g_file_global_const_int = 1337; } int main (int argc, char const *argv[]) { - return abc::g_file_global_int; // Set break point at this line. + int unused = abc::g_file_global_const_int; + return abc::g_file_global_int; // Set break point at this line. } Index: lldb/test/API/lang/cpp/global_variables/TestCPPGlobalVariables.py =================================================================== --- lldb/test/API/lang/cpp/global_variables/TestCPPGlobalVariables.py +++ lldb/test/API/lang/cpp/global_variables/TestCPPGlobalVariables.py @@ -15,12 +15,11 @@ TestBase.setUp(self) self.source = lldb.SBFileSpec('main.cpp') - @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") def test(self): self.build() (target, _, _, _) = lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", self.source) - + # Check that we can access g_file_global_int by its name self.expect("target variable g_file_global_int", VARIABLES_DISPLAYED_CORRECTLY, substrs=['42']) @@ -29,6 +28,20 @@ self.expect("target variable xyz::g_file_global_int", VARIABLES_DISPLAYED_CORRECTLY, error=True, substrs=['can\'t find global variable']) + # Check that we can access g_file_global_const_int by its name + self.expect("target variable g_file_global_const_int", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['1337']) + self.expect("target variable abc::g_file_global_const_int", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['1337']) + self.expect("target variable xyz::g_file_global_const_int", VARIABLES_DISPLAYED_CORRECTLY, + error=True, substrs=['can\'t find global variable']) + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") + def test_access_by_mangled_name(self): + self.build() + + (target, _, _, _) = lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", self.source) + # Check that we can access g_file_global_int by its mangled name addr = target.EvaluateExpression("&abc::g_file_global_int").GetValueAsUnsigned() self.assertNotEqual(addr, 0) Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3278,7 +3278,8 @@ // able to generate a fully qualified name from the // declaration context. if ((parent_tag == DW_TAG_compile_unit || - parent_tag == DW_TAG_partial_unit) && + parent_tag == DW_TAG_partial_unit || + parent_tag == DW_TAG_namespace) && Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU()))) mangled = GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString();
Index: lldb/test/API/lang/cpp/global_variables/main.cpp =================================================================== --- lldb/test/API/lang/cpp/global_variables/main.cpp +++ lldb/test/API/lang/cpp/global_variables/main.cpp @@ -1,10 +1,12 @@ #include <stdio.h> namespace abc { - int g_file_global_int = 42; +int g_file_global_int = 42; +const int g_file_global_const_int = 1337; } int main (int argc, char const *argv[]) { - return abc::g_file_global_int; // Set break point at this line. + int unused = abc::g_file_global_const_int; + return abc::g_file_global_int; // Set break point at this line. } Index: lldb/test/API/lang/cpp/global_variables/TestCPPGlobalVariables.py =================================================================== --- lldb/test/API/lang/cpp/global_variables/TestCPPGlobalVariables.py +++ lldb/test/API/lang/cpp/global_variables/TestCPPGlobalVariables.py @@ -15,12 +15,11 @@ TestBase.setUp(self) self.source = lldb.SBFileSpec('main.cpp') - @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") def test(self): self.build() (target, _, _, _) = lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", self.source) - + # Check that we can access g_file_global_int by its name self.expect("target variable g_file_global_int", VARIABLES_DISPLAYED_CORRECTLY, substrs=['42']) @@ -29,6 +28,20 @@ self.expect("target variable xyz::g_file_global_int", VARIABLES_DISPLAYED_CORRECTLY, error=True, substrs=['can\'t find global variable']) + # Check that we can access g_file_global_const_int by its name + self.expect("target variable g_file_global_const_int", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['1337']) + self.expect("target variable abc::g_file_global_const_int", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['1337']) + self.expect("target variable xyz::g_file_global_const_int", VARIABLES_DISPLAYED_CORRECTLY, + error=True, substrs=['can\'t find global variable']) + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") + def test_access_by_mangled_name(self): + self.build() + + (target, _, _, _) = lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", self.source) + # Check that we can access g_file_global_int by its mangled name addr = target.EvaluateExpression("&abc::g_file_global_int").GetValueAsUnsigned() self.assertNotEqual(addr, 0) Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3278,7 +3278,8 @@ // able to generate a fully qualified name from the // declaration context. if ((parent_tag == DW_TAG_compile_unit || - parent_tag == DW_TAG_partial_unit) && + parent_tag == DW_TAG_partial_unit || + parent_tag == DW_TAG_namespace) && Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU()))) mangled = GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString();
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits