[Lldb-commits] [lldb] r334498 - lldb-test symbols: Add -file argument and the ability to dump global variables in a file

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue Jun 12 05:57:36 PDT 2018


Author: labath
Date: Tue Jun 12 05:57:36 2018
New Revision: 334498

URL: http://llvm.org/viewvc/llvm-project?rev=334498&view=rev
Log:
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.

Added:
    lldb/trunk/lit/SymbolFile/DWARF/Inputs/
    lldb/trunk/lit/SymbolFile/DWARF/Inputs/find-variable-file-2.cpp
    lldb/trunk/lit/SymbolFile/DWARF/find-variable-file.cpp
Modified:
    lldb/trunk/lit/lit.cfg
    lldb/trunk/tools/lldb-test/lldb-test.cpp

Added: lldb/trunk/lit/SymbolFile/DWARF/Inputs/find-variable-file-2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/Inputs/find-variable-file-2.cpp?rev=334498&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/Inputs/find-variable-file-2.cpp (added)
+++ lldb/trunk/lit/SymbolFile/DWARF/Inputs/find-variable-file-2.cpp Tue Jun 12 05:57:36 2018
@@ -0,0 +1,3 @@
+namespace two {
+int foo;
+}

Added: lldb/trunk/lit/SymbolFile/DWARF/find-variable-file.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/find-variable-file.cpp?rev=334498&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/find-variable-file.cpp (added)
+++ lldb/trunk/lit/SymbolFile/DWARF/find-variable-file.cpp Tue Jun 12 05:57:36 2018
@@ -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

Modified: lldb/trunk/lit/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/lit.cfg?rev=334498&r1=334497&r2=334498&view=diff
==============================================================================
--- lldb/trunk/lit/lit.cfg (original)
+++ lldb/trunk/lit/lit.cfg Tue Jun 12 05:57:36 2018
@@ -28,6 +28,8 @@ config.test_format = lit.formats.ShTest(
 # 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__)
 

Modified: lldb/trunk/tools/lldb-test/lldb-test.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-test/lldb-test.cpp?rev=334498&r1=334497&r2=334498&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-test/lldb-test.cpp (original)
+++ lldb/trunk/tools/lldb-test/lldb-test.cpp Tue Jun 12 05:57:36 2018
@@ -148,6 +148,10 @@ static FunctionNameType getFunctionNameF
 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:
 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 &
 
 } // 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(SymbolVend
     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_
     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_pri
 }
 
 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
   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
 
     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
   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;
-  }
-  if (Find == FindType::Function && Regex && getFunctionNameFlags() != 0) {
-    WithColor::error() << "Cannot search for types using both regular "
-                          "expressions and function-flags.\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 (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
       HadErrors = 1;
       continue;
     }
-    
+
     if (Error E = Action(*ModulePtr)) {
       WithColor::error() << toString(std::move(E)) << "\n";
       HadErrors = 1;




More information about the lldb-commits mailing list