diff options
author | Pavel Labath <labath@google.com> | 2018-06-12 12:57:36 +0000 |
---|---|---|
committer | Pavel Labath <labath@google.com> | 2018-06-12 12:57:36 +0000 |
commit | e6954cb2a1819abe0dd3b7cd46b41bc28302f155 (patch) | |
tree | 781fe55ee89ef8d8fec0253c03800653f18017be /lldb | |
parent | 3d671248abc0949fad063a390fba8c17aa545a40 (diff) | |
download | bcm5719-llvm-e6954cb2a1819abe0dd3b7cd46b41bc28302f155.tar.gz bcm5719-llvm-e6954cb2a1819abe0dd3b7cd46b41bc28302f155.zip |
lldb-test symbols: Add -file argument and the ability to dump global variables in a file
The motivation for this is to be able to Dwarf index ability to look up
variables within a given compilation unit. It also fits in with the
patch in progress at D47939, which will add the ability to look up
funtions using file+line pairs.
The verification of which lldb-test options can be used together was
getting a bit unwieldy, so I moved the logic out into a separate
function.
llvm-svn: 334498
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/lit/SymbolFile/DWARF/Inputs/find-variable-file-2.cpp | 3 | ||||
-rw-r--r-- | lldb/lit/SymbolFile/DWARF/find-variable-file.cpp | 20 | ||||
-rw-r--r-- | lldb/lit/lit.cfg | 2 | ||||
-rw-r--r-- | lldb/tools/lldb-test/lldb-test.cpp | 174 |
4 files changed, 126 insertions, 73 deletions
diff --git a/lldb/lit/SymbolFile/DWARF/Inputs/find-variable-file-2.cpp b/lldb/lit/SymbolFile/DWARF/Inputs/find-variable-file-2.cpp new file mode 100644 index 00000000000..cd02cb07c62 --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/Inputs/find-variable-file-2.cpp @@ -0,0 +1,3 @@ +namespace two { +int foo; +} diff --git a/lldb/lit/SymbolFile/DWARF/find-variable-file.cpp b/lldb/lit/SymbolFile/DWARF/find-variable-file.cpp new file mode 100644 index 00000000000..4f0cb573aea --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/find-variable-file.cpp @@ -0,0 +1,20 @@ +// REQUIRES: lld + +// RUN: clang -g -c -o %t-1.o --target=x86_64-pc-linux %s +// RUN: clang -g -c -o %t-2.o --target=x86_64-pc-linux %S/Inputs/find-variable-file-2.cpp +// RUN: ld.lld %t-1.o %t-2.o -o %t +// RUN: lldb-test symbols --file=find-variable-file.cpp --find=variable %t | \ +// RUN: FileCheck --check-prefix=ONE %s +// RUN: lldb-test symbols --file=find-variable-file-2.cpp --find=variable %t | \ +// RUN: FileCheck --check-prefix=TWO %s + +// ONE: Found 1 variables: +namespace one { +int foo; +// ONE-DAG: name = "foo", type = {{.*}} (int), {{.*}} decl = find-variable-file.cpp:[[@LINE-1]] +} // namespace one + +extern "C" void _start() {} + +// TWO: Found 1 variables: +// TWO-DAG: name = "foo", {{.*}} decl = find-variable-file-2.cpp:2 diff --git a/lldb/lit/lit.cfg b/lldb/lit/lit.cfg index fae8834524e..7e1fcf7520c 100644 --- a/lldb/lit/lit.cfg +++ b/lldb/lit/lit.cfg @@ -28,6 +28,8 @@ config.test_format = lit.formats.ShTest(execute_external) # suffixes: We only support unit tests config.suffixes = [] +config.excludes = ['Inputs'] + # test_source_root: The root path where tests are located. config.test_source_root = os.path.dirname(__file__) diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp index c37d56ae7d0..223ee6b91a3 100644 --- a/lldb/tools/lldb-test/lldb-test.cpp +++ b/lldb/tools/lldb-test/lldb-test.cpp @@ -148,6 +148,10 @@ static FunctionNameType getFunctionNameFlags() { static cl::opt<bool> Verify("verify", cl::desc("Verify symbol information."), cl::sub(SymbolsSubcommand)); +static cl::opt<std::string> File("file", + cl::desc("File (compile unit) to search."), + cl::sub(SymbolsSubcommand)); + static Expected<CompilerDeclContext> getDeclContext(SymbolVendor &Vendor); static Error findFunctions(lldb_private::Module &Module); @@ -157,6 +161,7 @@ static Error findVariables(lldb_private::Module &Module); static Error dumpModule(lldb_private::Module &Module); static Error verify(lldb_private::Module &Module); +static Expected<Error (&)(lldb_private::Module &)> getAction(); static int dumpSymbols(Debugger &Dbg); } @@ -197,6 +202,13 @@ int evaluateMemoryMapCommands(Debugger &Dbg); } // namespace opts +template <typename... Args> +static Error make_string_error(const char *Format, Args &&... args) { + return llvm::make_error<llvm::StringError>( + llvm::formatv(Format, std::forward<Args>(args)...).str(), + llvm::inconvertibleErrorCode()); +} + TargetSP opts::createTarget(Debugger &Dbg, const std::string &Filename) { TargetSP Target; Status ST = @@ -312,14 +324,10 @@ opts::symbols::getDeclContext(SymbolVendor &Vendor) { return CompilerDeclContext(); VariableList List; Vendor.FindGlobalVariables(ConstString(Context), nullptr, UINT32_MAX, List); - if (List.Empty()) { - return make_error<StringError>("Context search didn't find a match.", - inconvertibleErrorCode()); - } - if (List.GetSize() > 1) { - return make_error<StringError>("Context search found multiple matches.", - inconvertibleErrorCode()); - } + if (List.Empty()) + return make_string_error("Context search didn't find a match."); + if (List.GetSize() > 1) + return make_string_error("Context search found multiple matches."); return List.GetVariableAtIndex(0)->GetDeclContext(); } @@ -394,6 +402,22 @@ Error opts::symbols::findVariables(lldb_private::Module &Module) { RegularExpression RE(Name); assert(RE.IsValid()); Vendor.FindGlobalVariables(RE, UINT32_MAX, List); + } else if (!File.empty()) { + CompUnitSP CU; + for (size_t Ind = 0; !CU && Ind < Module.GetNumCompileUnits(); ++Ind) { + CompUnitSP Candidate = Module.GetCompileUnitAtIndex(Ind); + if (!Candidate || Candidate->GetFilename().GetStringRef() != File) + continue; + if (CU) + return make_string_error("Multiple compile units for file `{0}` found.", + File); + CU = std::move(Candidate); + } + + if (!CU) + return make_string_error("Compile unit `{0}` not found.", File); + + List.AddVariables(CU->GetVariableList(true).get()); } else { Expected<CompilerDeclContext> ContextOr = getDeclContext(Vendor); if (!ContextOr) @@ -419,15 +443,11 @@ Error opts::symbols::dumpModule(lldb_private::Module &Module) { } Error opts::symbols::verify(lldb_private::Module &Module) { - SymbolVendor *plugin = Module.GetSymbolVendor(); - if (!plugin) - return make_error<StringError>("Can't get a symbol vendor.", - inconvertibleErrorCode()); + SymbolVendor &plugin = *Module.GetSymbolVendor(); - SymbolFile *symfile = plugin->GetSymbolFile(); + SymbolFile *symfile = plugin.GetSymbolFile(); if (!symfile) - return make_error<StringError>("Can't get a symbol file.", - inconvertibleErrorCode()); + return make_string_error("Module has no symbol file."); uint32_t comp_units_count = symfile->GetNumCompileUnits(); @@ -436,17 +456,14 @@ Error opts::symbols::verify(lldb_private::Module &Module) { for (uint32_t i = 0; i < comp_units_count; i++) { lldb::CompUnitSP comp_unit = symfile->ParseCompileUnitAtIndex(i); if (!comp_unit) - return make_error<StringError>("Can't get a compile unit.", - inconvertibleErrorCode()); + return make_string_error("Connot parse compile unit {0}.", i); outs() << "Processing '" << comp_unit->GetFilename().AsCString() << "' compile unit.\n"; LineTable *lt = comp_unit->GetLineTable(); if (!lt) - return make_error<StringError>( - "Can't get a line table of a compile unit.", - inconvertibleErrorCode()); + return make_string_error("Can't get a line table of a compile unit."); uint32_t count = lt->GetSize(); @@ -457,23 +474,18 @@ Error opts::symbols::verify(lldb_private::Module &Module) { LineEntry le; if (!lt->GetLineEntryAtIndex(0, le)) - return make_error<StringError>( - "Can't get a line entry of a compile unit", - inconvertibleErrorCode()); + return make_string_error("Can't get a line entry of a compile unit."); for (uint32_t i = 1; i < count; i++) { lldb::addr_t curr_end = le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize(); if (!lt->GetLineEntryAtIndex(i, le)) - return make_error<StringError>( - "Can't get a line entry of a compile unit", - inconvertibleErrorCode()); + return make_string_error("Can't get a line entry of a compile unit"); if (curr_end > le.range.GetBaseAddress().GetFileAddress()) - return make_error<StringError>( - "Line table of a compile unit is inconsistent", - inconvertibleErrorCode()); + return make_string_error( + "Line table of a compile unit is inconsistent."); } } @@ -482,53 +494,69 @@ Error opts::symbols::verify(lldb_private::Module &Module) { return Error::success(); } -int opts::symbols::dumpSymbols(Debugger &Dbg) { - if (Verify && Find != FindType::None) { - WithColor::error() << "Cannot both search and verify symbol information.\n"; - return 1; - } - if (Find != FindType::None && Regex && !Context.empty()) { - WithColor::error() - << "Cannot search using both regular expressions and context.\n"; - return 1; - } - if ((Find == FindType::Type || Find == FindType::Namespace) && Regex) { - WithColor::error() << "Cannot search for types and namespaces using " - "regular expressions.\n"; - return 1; +Expected<Error (&)(lldb_private::Module &)> opts::symbols::getAction() { + if (Verify) { + if (Find != FindType::None) + return make_string_error( + "Cannot both search and verify symbol information."); + if (Regex || !Context.empty() || !Name.empty() || !File.empty()) + return make_string_error("-regex, -context, -name and -file options are not " + "applicable for symbol verification."); + return verify; } - if (Find == FindType::Function && Regex && getFunctionNameFlags() != 0) { - WithColor::error() << "Cannot search for types using both regular " - "expressions and function-flags.\n"; - return 1; + + if (Regex && !Context.empty()) + return make_string_error( + "Cannot search using both regular expressions and context."); + + if (Regex && !RegularExpression(Name).IsValid()) + return make_string_error("`{0}` is not a valid regular expression.", Name); + + if (Regex + !Context.empty() + !File.empty() >= 2) + return make_string_error( + "Only one of -regex, -context and -file may be used simultaneously."); + if (Regex && Name.empty()) + return make_string_error("-regex used without a -name"); + + switch (Find) { + case FindType::None: + if (!Context.empty() || !Name.empty() || !File.empty()) + return make_string_error( + "Specify search type (-find) to use search options."); + return dumpModule; + + case FindType::Function: + if (!File.empty()) + return make_string_error("Cannot search for functions by file name."); + if (Regex && getFunctionNameFlags() != 0) + return make_string_error("Cannot search for functions using both regular " + "expressions and function-flags."); + return findFunctions; + + case FindType::Namespace: + if (Regex || !File.empty()) + return make_string_error("Cannot search for namespaces using regular " + "expressions or file names."); + return findNamespaces; + + case FindType::Type: + if (Regex || !File.empty()) + return make_string_error("Cannot search for types using regular " + "expressions or file names."); + return findTypes; + + case FindType::Variable: + return findVariables; } - if (Regex && !RegularExpression(Name).IsValid()) { - WithColor::error() << "`" << Name - << "` is not a valid regular expression.\n"; +} + +int opts::symbols::dumpSymbols(Debugger &Dbg) { + auto ActionOr = getAction(); + if (!ActionOr) { + logAllUnhandledErrors(ActionOr.takeError(), WithColor::error(), ""); return 1; } - - Error (*Action)(lldb_private::Module &); - if (!Verify) { - switch (Find) { - case FindType::Function: - Action = findFunctions; - break; - case FindType::Namespace: - Action = findNamespaces; - break; - case FindType::Type: - Action = findTypes; - break; - case FindType::Variable: - Action = findVariables; - break; - case FindType::None: - Action = dumpModule; - break; - } - } else - Action = verify; + auto Action = *ActionOr; int HadErrors = 0; for (const auto &File : InputFilenames) { @@ -543,7 +571,7 @@ int opts::symbols::dumpSymbols(Debugger &Dbg) { HadErrors = 1; continue; } - + if (Error E = Action(*ModulePtr)) { WithColor::error() << toString(std::move(E)) << "\n"; HadErrors = 1; |