forked from OSchip/llvm-project
Provide a mechanism to do some pre-loading of symbols up front.
Loading a shared library can require a large amount of work; rather than do that serially for each library, this patch will allow parallelization of the symbols and debug info name indexes. From scott.smith@purestorage.com https://reviews.llvm.org/D32598 llvm-svn: 301609
This commit is contained in:
parent
b242e93541
commit
7fca8c0757
|
@ -614,6 +614,8 @@ public:
|
||||||
|
|
||||||
const FileSpec &GetSymbolFileFileSpec() const { return m_symfile_spec; }
|
const FileSpec &GetSymbolFileFileSpec() const { return m_symfile_spec; }
|
||||||
|
|
||||||
|
void PreloadSymbols();
|
||||||
|
|
||||||
void SetSymbolFileFileSpec(const FileSpec &file);
|
void SetSymbolFileFileSpec(const FileSpec &file);
|
||||||
|
|
||||||
const llvm::sys::TimePoint<> &GetModificationTime() const {
|
const llvm::sys::TimePoint<> &GetModificationTime() const {
|
||||||
|
|
|
@ -180,6 +180,8 @@ public:
|
||||||
uint32_t type_mask,
|
uint32_t type_mask,
|
||||||
lldb_private::TypeList &type_list) = 0;
|
lldb_private::TypeList &type_list) = 0;
|
||||||
|
|
||||||
|
virtual void PreloadSymbols();
|
||||||
|
|
||||||
virtual lldb_private::TypeSystem *
|
virtual lldb_private::TypeSystem *
|
||||||
GetTypeSystemForLanguage(lldb::LanguageType language);
|
GetTypeSystemForLanguage(lldb::LanguageType language);
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
Symtab(ObjectFile *objfile);
|
Symtab(ObjectFile *objfile);
|
||||||
~Symtab();
|
~Symtab();
|
||||||
|
|
||||||
|
void PreloadSymbols();
|
||||||
void Reserve(size_t count);
|
void Reserve(size_t count);
|
||||||
Symbol *Resize(size_t count);
|
Symbol *Resize(size_t count);
|
||||||
uint32_t AddSymbol(const Symbol &symbol);
|
uint32_t AddSymbol(const Symbol &symbol);
|
||||||
|
|
|
@ -82,6 +82,10 @@ public:
|
||||||
|
|
||||||
bool SetPreferDynamicValue(lldb::DynamicValueType d);
|
bool SetPreferDynamicValue(lldb::DynamicValueType d);
|
||||||
|
|
||||||
|
bool GetPreloadSymbols() const;
|
||||||
|
|
||||||
|
void SetPreloadSymbols(bool b);
|
||||||
|
|
||||||
bool GetDisableASLR() const;
|
bool GetDisableASLR() const;
|
||||||
|
|
||||||
void SetDisableASLR(bool b);
|
void SetDisableASLR(bool b);
|
||||||
|
|
|
@ -13,14 +13,13 @@ class SharedLibTestCase(TestBase):
|
||||||
|
|
||||||
mydir = TestBase.compute_mydir(__file__)
|
mydir = TestBase.compute_mydir(__file__)
|
||||||
|
|
||||||
def test_expr(self):
|
def common_test_expr(self, preload_symbols):
|
||||||
"""Test that types work when defined in a shared library and forward-declared in the main executable"""
|
|
||||||
if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion():
|
if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion():
|
||||||
self.skipTest(
|
self.skipTest(
|
||||||
"llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef")
|
"llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef")
|
||||||
|
|
||||||
self.build()
|
self.build()
|
||||||
self.common_setup()
|
self.common_setup(preload_symbols)
|
||||||
|
|
||||||
# This should display correctly.
|
# This should display correctly.
|
||||||
self.expect(
|
self.expect(
|
||||||
|
@ -31,6 +30,18 @@ class SharedLibTestCase(TestBase):
|
||||||
"(sub_foo)",
|
"(sub_foo)",
|
||||||
"other_element = 3"])
|
"other_element = 3"])
|
||||||
|
|
||||||
|
self.expect(
|
||||||
|
"expression GetMeASubFoo(my_foo_ptr)",
|
||||||
|
startstr="(sub_foo *) $")
|
||||||
|
|
||||||
|
def test_expr(self):
|
||||||
|
"""Test that types work when defined in a shared library and forward-declared in the main executable"""
|
||||||
|
self.common_test_expr(True)
|
||||||
|
|
||||||
|
def test_expr_no_preload(self):
|
||||||
|
"""Test that types work when defined in a shared library and forward-declared in the main executable, but with preloading disabled"""
|
||||||
|
self.common_test_expr(False)
|
||||||
|
|
||||||
@unittest2.expectedFailure("rdar://problem/10704639")
|
@unittest2.expectedFailure("rdar://problem/10704639")
|
||||||
def test_frame_variable(self):
|
def test_frame_variable(self):
|
||||||
"""Test that types work when defined in a shared library and forward-declared in the main executable"""
|
"""Test that types work when defined in a shared library and forward-declared in the main executable"""
|
||||||
|
@ -54,7 +65,7 @@ class SharedLibTestCase(TestBase):
|
||||||
self.line = line_number(self.source, '// Set breakpoint 0 here.')
|
self.line = line_number(self.source, '// Set breakpoint 0 here.')
|
||||||
self.shlib_names = ["foo"]
|
self.shlib_names = ["foo"]
|
||||||
|
|
||||||
def common_setup(self):
|
def common_setup(self, preload_symbols = True):
|
||||||
# Run in synchronous mode
|
# Run in synchronous mode
|
||||||
self.dbg.SetAsync(False)
|
self.dbg.SetAsync(False)
|
||||||
|
|
||||||
|
@ -62,6 +73,8 @@ class SharedLibTestCase(TestBase):
|
||||||
target = self.dbg.CreateTarget("a.out")
|
target = self.dbg.CreateTarget("a.out")
|
||||||
self.assertTrue(target, VALID_TARGET)
|
self.assertTrue(target, VALID_TARGET)
|
||||||
|
|
||||||
|
self.runCmd("settings set target.preload-symbols " + str(preload_symbols).lower())
|
||||||
|
|
||||||
# Break inside the foo function which takes a bar_ptr argument.
|
# Break inside the foo function which takes a bar_ptr argument.
|
||||||
lldbutil.run_break_set_by_file_and_line(
|
lldbutil.run_break_set_by_file_and_line(
|
||||||
self, self.source, self.line, num_expected_locations=1, loc_exact=True)
|
self, self.source, self.line, num_expected_locations=1, loc_exact=True)
|
||||||
|
|
|
@ -1432,6 +1432,22 @@ size_t Module::FindSymbolsMatchingRegExAndType(const RegularExpression ®ex,
|
||||||
return sc_list.GetSize() - initial_size;
|
return sc_list.GetSize() - initial_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Module::PreloadSymbols() {
|
||||||
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
||||||
|
SymbolVendor * sym_vendor = GetSymbolVendor();
|
||||||
|
if (!sym_vendor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Prime the symbol file first, since it adds symbols to the symbol table.
|
||||||
|
if (SymbolFile *symbol_file = sym_vendor->GetSymbolFile()) {
|
||||||
|
symbol_file->PreloadSymbols();
|
||||||
|
}
|
||||||
|
// Now we can prime the symbol table.
|
||||||
|
if (Symtab * symtab = sym_vendor->GetSymtab()) {
|
||||||
|
symtab->PreloadSymbols();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Module::SetSymbolFileFileSpec(const FileSpec &file) {
|
void Module::SetSymbolFileFileSpec(const FileSpec &file) {
|
||||||
if (!file.Exists())
|
if (!file.Exists())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1917,6 +1917,12 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
|
||||||
return sc_list.GetSize() - prev_size;
|
return sc_list.GetSize() - prev_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SymbolFileDWARF::PreloadSymbols() {
|
||||||
|
std::lock_guard<std::recursive_mutex> guard(
|
||||||
|
GetObjectFile()->GetModule()->GetMutex());
|
||||||
|
Index();
|
||||||
|
}
|
||||||
|
|
||||||
void SymbolFileDWARF::Index() {
|
void SymbolFileDWARF::Index() {
|
||||||
if (m_indexed)
|
if (m_indexed)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -226,6 +226,8 @@ public:
|
||||||
const lldb_private::ConstString &name,
|
const lldb_private::ConstString &name,
|
||||||
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
|
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
|
||||||
|
|
||||||
|
void PreloadSymbols() override;
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// PluginInterface protocol
|
// PluginInterface protocol
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
|
|
||||||
using namespace lldb_private;
|
using namespace lldb_private;
|
||||||
|
|
||||||
|
void SymbolFile::PreloadSymbols() {
|
||||||
|
// No-op for most implementations.
|
||||||
|
}
|
||||||
|
|
||||||
SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) {
|
SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) {
|
||||||
std::unique_ptr<SymbolFile> best_symfile_ap;
|
std::unique_ptr<SymbolFile> best_symfile_ap;
|
||||||
if (obj_file != nullptr) {
|
if (obj_file != nullptr) {
|
||||||
|
|
|
@ -427,6 +427,11 @@ void Symtab::InitNameIndexes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Symtab::PreloadSymbols() {
|
||||||
|
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
||||||
|
InitNameIndexes();
|
||||||
|
}
|
||||||
|
|
||||||
void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes,
|
void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes,
|
||||||
bool add_demangled, bool add_mangled,
|
bool add_demangled, bool add_mangled,
|
||||||
NameToIndexMap &name_to_index_map) const {
|
NameToIndexMap &name_to_index_map) const {
|
||||||
|
|
|
@ -1870,6 +1870,11 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preload symbols outside of any lock, so hopefully we can do this for
|
||||||
|
// each library in parallel.
|
||||||
|
if (GetPreloadSymbols())
|
||||||
|
module_sp->PreloadSymbols();
|
||||||
|
|
||||||
if (old_module_sp &&
|
if (old_module_sp &&
|
||||||
m_images.GetIndexForModule(old_module_sp.get()) !=
|
m_images.GetIndexForModule(old_module_sp.get()) !=
|
||||||
LLDB_INVALID_INDEX32) {
|
LLDB_INVALID_INDEX32) {
|
||||||
|
@ -3277,6 +3282,8 @@ static PropertyDefinition g_properties[] = {
|
||||||
{"detach-on-error", OptionValue::eTypeBoolean, false, true, nullptr,
|
{"detach-on-error", OptionValue::eTypeBoolean, false, true, nullptr,
|
||||||
nullptr, "debugserver will detach (rather than killing) a process if it "
|
nullptr, "debugserver will detach (rather than killing) a process if it "
|
||||||
"loses connection with lldb."},
|
"loses connection with lldb."},
|
||||||
|
{"preload-symbols", OptionValue::eTypeBoolean, false, true, nullptr, nullptr,
|
||||||
|
"Enable loading of symbol tables before they are needed."},
|
||||||
{"disable-aslr", OptionValue::eTypeBoolean, false, true, nullptr, nullptr,
|
{"disable-aslr", OptionValue::eTypeBoolean, false, true, nullptr, nullptr,
|
||||||
"Disable Address Space Layout Randomization (ASLR)"},
|
"Disable Address Space Layout Randomization (ASLR)"},
|
||||||
{"disable-stdio", OptionValue::eTypeBoolean, false, false, nullptr, nullptr,
|
{"disable-stdio", OptionValue::eTypeBoolean, false, false, nullptr, nullptr,
|
||||||
|
@ -3379,6 +3386,7 @@ enum {
|
||||||
ePropertyOutputPath,
|
ePropertyOutputPath,
|
||||||
ePropertyErrorPath,
|
ePropertyErrorPath,
|
||||||
ePropertyDetachOnError,
|
ePropertyDetachOnError,
|
||||||
|
ePropertyPreloadSymbols,
|
||||||
ePropertyDisableASLR,
|
ePropertyDisableASLR,
|
||||||
ePropertyDisableSTDIO,
|
ePropertyDisableSTDIO,
|
||||||
ePropertyInlineStrategy,
|
ePropertyInlineStrategy,
|
||||||
|
@ -3641,6 +3649,17 @@ bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) {
|
||||||
return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, d);
|
return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TargetProperties::GetPreloadSymbols() const {
|
||||||
|
const uint32_t idx = ePropertyPreloadSymbols;
|
||||||
|
return m_collection_sp->GetPropertyAtIndexAsBoolean(
|
||||||
|
nullptr, idx, g_properties[idx].default_uint_value != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetProperties::SetPreloadSymbols(bool b) {
|
||||||
|
const uint32_t idx = ePropertyPreloadSymbols;
|
||||||
|
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
|
||||||
|
}
|
||||||
|
|
||||||
bool TargetProperties::GetDisableASLR() const {
|
bool TargetProperties::GetDisableASLR() const {
|
||||||
const uint32_t idx = ePropertyDisableASLR;
|
const uint32_t idx = ePropertyDisableASLR;
|
||||||
return m_collection_sp->GetPropertyAtIndexAsBoolean(
|
return m_collection_sp->GetPropertyAtIndexAsBoolean(
|
||||||
|
|
Loading…
Reference in New Issue