This revision was automatically updated to reflect the committed changes.
Closed by commit rGfc743f034a34: Report which modules have forcefully completed
types in statistics. (authored by clayborg).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D138638/new/
https://reviews.llvm.org/D138638
Files:
lldb/include/lldb/Symbol/TypeSystem.h
lldb/include/lldb/Target/Statistics.h
lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
lldb/source/Target/Statistics.cpp
lldb/test/API/commands/statistics/basic/TestStats.py
lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
Index: lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
===================================================================
--- lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
+++ lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
@@ -30,6 +30,23 @@
self._check_type(target, "InheritsFromOne")
self._check_type(target, "InheritsFromTwo")
+ # Check that the statistics show that we had incomplete debug info.
+ stats = self.get_stats()
+ # Find the a.out module info in the stats and verify it has the
+ # "debugInfoHadIncompleteTypes" key value pair set to True
+ exe_module_found = False
+ for module in stats['modules']:
+ if module['path'].endswith('a.out'):
+ self.assertTrue(module['debugInfoHadIncompleteTypes'])
+ exe_module_found = True
+ break
+ self.assertTrue(exe_module_found)
+ # Verify that "totalModuleCountWithIncompleteTypes" at the top level
+ # is greater than zero which shows we had incomplete debug info in a
+ # module
+ self.assertGreater(stats['totalModuleCountWithIncompleteTypes'], 0)
+
+
def _check_incomplete_frame_variable_output(self):
# Check that the display of the "frame variable" output identifies the
# incomplete types. Currently the expression parser will find the real
Index: lldb/test/API/commands/statistics/basic/TestStats.py
===================================================================
--- lldb/test/API/commands/statistics/basic/TestStats.py
+++ lldb/test/API/commands/statistics/basic/TestStats.py
@@ -55,30 +55,6 @@
self.assertEqual(success_fail_dict['failures'], num_fails,
'make sure success count')
- def get_stats(self, options=None, log_path=None):
- """
- Get the output of the "statistics dump" with optional extra options
- and return the JSON as a python dictionary.
- """
- # If log_path is set, open the path and emit the output of the command
- # for debugging purposes.
- if log_path is not None:
- f = open(log_path, 'w')
- else:
- f = None
- return_obj = lldb.SBCommandReturnObject()
- command = "statistics dump "
- if options is not None:
- command += options
- if f:
- f.write('(lldb) %s\n' % (command))
- self.ci.HandleCommand(command, return_obj, False)
- metrics_json = return_obj.GetOutput()
- if f:
- f.write(metrics_json)
- return json.loads(metrics_json)
-
-
def get_target_stats(self, debug_stats):
if "targets" in debug_stats:
return debug_stats["targets"][0]
@@ -509,7 +485,6 @@
exe_name = 'a.out'
exe = self.getBuildArtifact(exe_name)
dsym = self.getBuildArtifact(exe_name + ".dSYM")
- print("carp: dsym = '%s'" % (dsym))
# Make sure the executable file exists after building.
self.assertEqual(os.path.exists(exe), True)
# Make sure the dSYM file doesn't exist after building.
@@ -563,7 +538,6 @@
exe = self.getBuildArtifact(exe_name)
dsym = self.getBuildArtifact(exe_name + ".dSYM")
main_obj = self.getBuildArtifact('main.o')
- print("carp: dsym = '%s'" % (dsym))
# Make sure the executable file exists after building.
self.assertEqual(os.path.exists(exe), True)
# Make sure the dSYM file doesn't exist after building.
Index: lldb/source/Target/Statistics.cpp
===================================================================
--- lldb/source/Target/Statistics.cpp
+++ lldb/source/Target/Statistics.cpp
@@ -65,6 +65,8 @@
module.try_emplace("debugInfoEnabled", debug_info_enabled);
module.try_emplace("debugInfoHadVariableErrors",
debug_info_had_variable_errors);
+ module.try_emplace("debugInfoHadIncompleteTypes",
+ debug_info_had_incomplete_types);
module.try_emplace("symbolTableStripped", symtab_stripped);
if (!symfile_path.empty())
module.try_emplace("symbolFilePath", symfile_path);
@@ -207,6 +209,7 @@
uint32_t num_debug_info_enabled_modules = 0;
uint32_t num_modules_has_debug_info = 0;
uint32_t num_modules_with_variable_errors = 0;
+ uint32_t num_modules_with_incomplete_types = 0;
uint32_t num_stripped_modules = 0;
for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
@@ -273,8 +276,13 @@
module->ForEachTypeSystem([&](lldb::TypeSystemSP ts) {
if (auto stats = ts->ReportStatistics())
module_stat.type_system_stats.insert({ts->GetPluginName(), *stats});
+ if (ts->GetHasForcefullyCompletedTypes())
+ module_stat.debug_info_had_incomplete_types = true;
return true;
});
+ if (module_stat.debug_info_had_incomplete_types)
+ ++num_modules_with_incomplete_types;
+
json_modules.emplace_back(module_stat.ToJSON());
}
@@ -299,6 +307,7 @@
{"totalModuleCount", num_modules},
{"totalModuleCountHasDebugInfo", num_modules_has_debug_info},
{"totalModuleCountWithVariableErrors", num_modules_with_variable_errors},
+ {"totalModuleCountWithIncompleteTypes", num_modules_with_incomplete_types},
{"totalDebugInfoEnabled", num_debug_info_enabled_modules},
{"totalSymbolTableStripped", num_stripped_modules},
};
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -1063,6 +1063,8 @@
/// complete (base class, member, etc.).
static void RequireCompleteType(CompilerType type);
+ bool SetDeclIsForcefullyCompleted(const clang::TagDecl *td);
+
private:
/// Returns the PrintingPolicy used when generating the internal type names.
/// These type names are mostly used for the formatter selection.
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -9859,7 +9859,7 @@
const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type);
auto ts = type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
if (ts)
- ts->GetMetadata(td)->SetIsForcefullyCompleted();
+ ts->SetDeclIsForcefullyCompleted(td);
}
namespace {
@@ -10062,3 +10062,14 @@
}
return false;
}
+
+bool TypeSystemClang::SetDeclIsForcefullyCompleted(const clang::TagDecl *td) {
+ if (td == nullptr)
+ return false;
+ ClangASTMetadata *metadata = GetMetadata(td);
+ if (metadata == nullptr)
+ return false;
+ m_has_forcefully_completed_types = true;
+ metadata->SetIsForcefullyCompleted();
+ return true;
+}
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -226,7 +226,7 @@
auto ts_sp = type.GetTypeSystem();
auto ts = ts_sp.dyn_cast_or_null<TypeSystemClang>();
if (ts)
- ts->GetMetadata(td)->SetIsForcefullyCompleted();
+ ts->SetDeclIsForcefullyCompleted(td);
}
/// This function serves a similar purpose as RequireCompleteType above, but it
Index: lldb/packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -37,6 +37,7 @@
import gc
import glob
import io
+import json
import os.path
import re
import shutil
@@ -1642,6 +1643,19 @@
err = platform.Run(shell_command)
return (err, shell_command.GetStatus(), shell_command.GetOutput())
+ def get_stats(self, options=None):
+ """
+ Get the output of the "statistics dump" with optional extra options
+ and return the JSON as a python dictionary.
+ """
+ return_obj = lldb.SBCommandReturnObject()
+ command = "statistics dump "
+ if options is not None:
+ command += options
+ self.ci.HandleCommand(command, return_obj, False)
+ metrics_json = return_obj.GetOutput()
+ return json.loads(metrics_json)
+
# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
# We change the test methods to create a new test method for each test for each debug info we are
# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
@@ -2483,7 +2497,7 @@
error = obj.GetError()
self.fail(self._formatMessage(msg,
"'{}' is not success".format(error)))
-
+
"""Assert two states are equal"""
def assertState(self, first, second, msg=None):
if first != second:
Index: lldb/include/lldb/Target/Statistics.h
===================================================================
--- lldb/include/lldb/Target/Statistics.h
+++ lldb/include/lldb/Target/Statistics.h
@@ -121,6 +121,7 @@
bool debug_info_enabled = true;
bool symtab_stripped = false;
bool debug_info_had_variable_errors = false;
+ bool debug_info_had_incomplete_types = false;
};
struct ConstStringStats {
Index: lldb/include/lldb/Symbol/TypeSystem.h
===================================================================
--- lldb/include/lldb/Symbol/TypeSystem.h
+++ lldb/include/lldb/Symbol/TypeSystem.h
@@ -90,7 +90,7 @@
/// Free up any resources associated with this TypeSystem. Done before
/// removing all the TypeSystems from the TypeSystemMap.
virtual void Finalize() {}
-
+
virtual DWARFASTParser *GetDWARFParser() { return nullptr; }
virtual PDBASTParser *GetPDBParser() { return nullptr; }
virtual npdb::PdbAstBuilder *GetNativePDBParser() { return nullptr; }
@@ -516,8 +516,13 @@
virtual llvm::Optional<llvm::json::Value> ReportStatistics();
+ bool GetHasForcefullyCompletedTypes() const {
+ return m_has_forcefully_completed_types;
+ }
protected:
SymbolFile *m_sym_file = nullptr;
+ /// Used for reporting statistics.
+ bool m_has_forcefully_completed_types = false;
};
class TypeSystemMap {
@@ -541,6 +546,9 @@
GetTypeSystemForLanguage(lldb::LanguageType language, Target *target,
bool can_create);
+ /// Check all type systems in the map to see if any have forcefully completed
+ /// types;
+ bool GetHasForcefullyCompletedTypes() const;
protected:
typedef llvm::DenseMap<uint16_t, lldb::TypeSystemSP> collection;
mutable std::mutex m_mutex; ///< A mutex to keep this object happy in
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits