Include inlined functions when figuring out a contiguous address range
authorGreg Clayton <clayborg@gmail.com>
Mon, 6 May 2019 20:01:21 +0000 (20:01 +0000)
committerGreg Clayton <clayborg@gmail.com>
Mon, 6 May 2019 20:01:21 +0000 (20:01 +0000)
Checking this in for Antonio Afonso:

This diff changes the function LineEntry::GetSameLineContiguousAddressRange so that it also includes function calls that were inlined at the same line of code.

My motivation is to decrease the step over time of lines that heavly rely on inlined functions. I have multiple examples in the code base I work that makes a step over stop 20 or mote times internally. This can easly had up to step overs that take >500ms which I was able to lower to 25ms with this new strategy.

The reason the current code is not extending the address range beyond an inlined function is because when we resolve the symbol at the next address of the line entry we will get the entry line corresponding to where the original code for the inline function lives, making us barely extend the range. This then will end up on a step over having to stop multiple times everytime there's an inlined function.

To check if the range is an inlined function at that line I also get the block associated with the next address and check if there is a parent block with a call site at the line we're trying to extend.

To check this I created a new function in Block called GetContainingInlinedBlockWithCallSite that does exactly that. I also added a new function to Declaration for convinence of checking file/line named CompareFileAndLine.

To avoid potential issues when extending an address range I added an Extend function that extends the range by the AddressRange given as an argument. This function returns true to indicate sucess when the rage was agumented, false otherwise (e.g.: the ranges are not connected). The reason I do is to make sure that we're not just blindly extending complete_line_range by whatever GetByteSize() we got. If for some reason the ranges are not connected or overlap, or even 0, this could be an issue.

I also added a unit tests for this change and include the instructions on the test itself on how to generate the yaml file I use for testing.

Differential Revision: https://reviews.llvm.org/D61292

llvm-svn: 360071

24 files changed:
lldb/include/lldb/Core/AddressRange.h
lldb/include/lldb/Symbol/Block.h
lldb/include/lldb/Symbol/Declaration.h
lldb/include/lldb/Symbol/LineEntry.h
lldb/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme
lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
lldb/source/Core/AddressRange.cpp
lldb/source/Symbol/Block.cpp
lldb/source/Symbol/Declaration.cpp
lldb/source/Symbol/LineEntry.cpp
lldb/source/Target/Thread.cpp
lldb/source/Target/ThreadPlanStepOut.cpp
lldb/source/Target/ThreadPlanStepRange.cpp
lldb/tools/lldb-test/lldb-test.cpp
lldb/unittests/Core/CMakeLists.txt
lldb/unittests/Core/MangledTest.cpp
lldb/unittests/Interpreter/TestCompletion.cpp
lldb/unittests/ObjectFile/ELF/CMakeLists.txt
lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
lldb/unittests/Symbol/CMakeLists.txt
lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp
lldb/unittests/TestingSupport/CMakeLists.txt
lldb/unittests/TestingSupport/TestUtilities.cpp
lldb/unittests/TestingSupport/TestUtilities.h

index b55c279..832c08e 100644 (file)
@@ -163,6 +163,20 @@ public:
   ///     range, \b false otherwise.
   bool ContainsLoadAddress(lldb::addr_t load_addr, Target *target) const;
 
+  //------------------------------------------------------------------
+  /// Extends this range with \b rhs_range if it overlaps this range on the
+  /// right side. The range overlaps on the right side if the base address
+  /// of \b rhs_range lies within this range or if it's contiguous on its
+  /// right side.
+  ///
+  /// @param[in] rhs_range
+  ///     The range to extend at the right side.
+  ///
+  /// @return
+  ///     Returns \b true if this range was extended, \b false otherwise.
+  //------------------------------------------------------------------
+  bool Extend(const AddressRange &rhs_range);
+
   /// Dump a description of this object to a Stream.
   ///
   /// Dump a description of the contents of this object to the supplied stream
index 8c414a5..36d0944 100644 (file)
@@ -185,6 +185,22 @@ public:
   ///     parent.
   Block *GetInlinedParent();
 
+  //------------------------------------------------------------------
+  /// Get the inlined block at the given call site that contains this block.
+  ///
+  /// @param[in] find_call_site
+  ///     a declaration with the file and line of the call site to find.
+  ///
+  /// @return
+  ///     If this block contains inlined function info and is at the call
+  ///     site given by the file and line at the given \b declaration, then
+  ///     it will return this block, otherwise the parent blocks will be
+  ///     searched to see if any is at the call site. nullptr will be returned
+  ///     if no block is found at the call site.
+  //------------------------------------------------------------------
+  Block *
+  GetContainingInlinedBlockWithCallSite(const Declaration &find_call_site);
+
   /// Get the sibling block for this block.
   ///
   /// \return
index e2e600a..63798f8 100644 (file)
@@ -107,6 +107,17 @@ public:
   ///     \li 1 if lhs > rhs
   static int Compare(const Declaration &lhs, const Declaration &rhs);
 
+  /// Checks if this object has the same file and line as another declaration
+  /// object.
+  ///
+  /// \param[in] declaration
+  ///     The const Declaration object to compare with.
+  ///
+  /// \return
+  ///     Returns \b true if \b declaration is at the same file and
+  ///     line, \b false otherwise.
+  bool FileAndLineEqual(const Declaration &declaration) const;
+
   /// Dump a description of this object to a Stream.
   ///
   /// Dump a description of the contents of this object to the supplied stream
index 647fe87..fe97a78 100644 (file)
@@ -123,13 +123,21 @@ struct LineEntry {
   /// LineEntry (and it will include the range of the following LineEntries
   /// that match either 32 or 0.)
   ///
+  /// When \b include_inlined_functions is \b true inlined functions with
+  /// a call site at this LineEntry will also be included in the complete
+  /// range.
+  ///
   /// If the initial LineEntry this method is called on is a line #0, only the
   /// range of contiuous LineEntries with line #0 will be included in the
   /// complete range.
   ///
+  /// @param[in] include_inlined_functions
+  ///     Whether to include inlined functions at the same line or not.
+  ///
   /// \return
   ///     The contiguous AddressRange for this source line.
-  AddressRange GetSameLineContiguousAddressRange() const;
+  AddressRange
+  GetSameLineContiguousAddressRange(bool include_inlined_functions) const;
 
   /// Apply file mappings from target.source-map to the LineEntry's file.
   ///
index d31912e..178da5b 100644 (file)
       </AdditionalOptions>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "DebugClang"
+      buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      launchStyle = "1"
+      launchStyle = "0"
       useCustomWorkingDirectory = "NO"
       ignoresPersistentStateOnLaunch = "NO"
       debugDocumentVersioning = "YES"
             ReferencedContainer = "container:lldb.xcodeproj">
          </BuildableReference>
       </BuildableProductRunnable>
+      <CommandLineArguments>
+         <CommandLineArgument
+            argument = "-o &apos;command script import /Users/gclayton/fbsource/fbandroid/scripts/lldb/commands/fbsymbols.py&apos;"
+            isEnabled = "NO">
+         </CommandLineArgument>
+         <CommandLineArgument
+            argument = "-o &apos;log enable lldb unwind&apos; -o &apos;command script import /Users/gclayton/fbsource/fbandroid/scripts/lldb/commands/fbsymbols.py&apos; -o &apos;fbsymbols --minidump GLWubgKtZo80qCYDAAAAAADejTIHbggUAAAA&apos; -o &apos;command script import ~/Dropbox/bin/sbt.py&apos;"
+            isEnabled = "YES">
+         </CommandLineArgument>
+         <CommandLineArgument
+            argument = "-o &apos;fbsymbols --minidump GLWubgKtZo80qCYDAAAAAADejTIHbggUAAAA&apos;"
+            isEnabled = "NO">
+         </CommandLineArgument>
+      </CommandLineArguments>
       <AdditionalOptions>
       </AdditionalOptions>
    </LaunchAction>
index f13dc97..1072df3 100644 (file)
       </AdditionalOptions>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "DebugClang"
+      buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      launchStyle = "1"
+      launchStyle = "0"
       useCustomWorkingDirectory = "NO"
       customWorkingDirectory = "/Volumes/work/gclayton/Documents/devb/attach"
       ignoresPersistentStateOnLaunch = "YES"
             ReferencedContainer = "container:lldb.xcodeproj">
          </BuildableReference>
       </BuildableProductRunnable>
+      <CommandLineArguments>
+         <CommandLineArgument
+            argument = "-o &apos;command script import /Users/gclayton/fbsource/fbandroid/scripts/lldb/commands/fbsymbols.py&apos;"
+            isEnabled = "YES">
+         </CommandLineArgument>
+         <CommandLineArgument
+            argument = "--no-use-colors"
+            isEnabled = "YES">
+         </CommandLineArgument>
+         <CommandLineArgument
+            argument = "-o &apos;fbsymbols --minidump GLWubgKtZo80qCYDAAAAAADejTIHbggUAAAA&apos;"
+            isEnabled = "YES">
+         </CommandLineArgument>
+      </CommandLineArguments>
       <EnvironmentVariables>
          <EnvironmentVariable
             key = "LLDB_LAUNCH_FLAG_DISABLE_ASLR"
index f236840..71eec3c 100644 (file)
@@ -122,6 +122,24 @@ bool AddressRange::ContainsLoadAddress(addr_t load_addr, Target *target) const {
   return false;
 }
 
+bool AddressRange::Extend(const AddressRange &rhs_range) {
+  addr_t lhs_end_addr = GetBaseAddress().GetFileAddress() + GetByteSize();
+  addr_t rhs_base_addr = rhs_range.GetBaseAddress().GetFileAddress();
+
+  if (!ContainsFileAddress(rhs_range.GetBaseAddress()) &&
+      lhs_end_addr != rhs_base_addr)
+    // The ranges don't intersect at all on the right side of this range.
+    return false;
+
+  addr_t rhs_end_addr = rhs_base_addr + rhs_range.GetByteSize();
+  if (lhs_end_addr >= rhs_end_addr)
+    // The rhs range totally overlaps this one, nothing to add.
+    return false;
+
+  m_byte_size += rhs_end_addr - lhs_end_addr;
+  return true;
+}
+
 void AddressRange::Clear() {
   m_base_addr.Clear();
   m_byte_size = 0;
index 6a0c37b..5d4db03 100644 (file)
@@ -212,6 +212,21 @@ Block *Block::GetInlinedParent() {
   return nullptr;
 }
 
+Block *Block::GetContainingInlinedBlockWithCallSite(
+    const Declaration &find_call_site) {
+  auto inlined_block = GetContainingInlinedBlock();
+
+  while (inlined_block) {
+    auto function_info = inlined_block->GetInlinedFunctionInfo();
+
+    if (function_info &&
+        function_info->GetCallSite().FileAndLineEqual(find_call_site))
+      return inlined_block;
+    inlined_block = inlined_block->GetInlinedParent();
+  }
+  return nullptr;
+}
+
 bool Block::GetRangeContainingOffset(const addr_t offset, Range &range) {
   const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
   if (range_ptr) {
index a1c6068..d78ba96 100644 (file)
@@ -83,6 +83,11 @@ int Declaration::Compare(const Declaration &a, const Declaration &b) {
   return 0;
 }
 
+bool Declaration::FileAndLineEqual(const Declaration &declaration) const {
+  int file_compare = FileSpec::Compare(this->m_file, declaration.m_file, true);
+  return file_compare == 0 && this->m_line == declaration.m_line;
+}
+
 bool lldb_private::operator==(const Declaration &lhs, const Declaration &rhs) {
 #ifdef LLDB_ENABLE_DECLARATION_COLUMNS
   if (lhs.GetColumn() == rhs.GetColumn())
index 94887a0..959a327 100644 (file)
@@ -190,40 +190,62 @@ int LineEntry::Compare(const LineEntry &a, const LineEntry &b) {
   return FileSpec::Compare(a.file, b.file, true);
 }
 
-AddressRange LineEntry::GetSameLineContiguousAddressRange() const {
+AddressRange LineEntry::GetSameLineContiguousAddressRange(
+    bool include_inlined_functions) const {
   // Add each LineEntry's range to complete_line_range until we find a
   // different file / line number.
   AddressRange complete_line_range = range;
+  auto symbol_context_scope = lldb::eSymbolContextLineEntry;
+  Declaration start_call_site(original_file, line);
+  if (include_inlined_functions)
+    symbol_context_scope |= lldb::eSymbolContextBlock;
 
   while (true) {
     SymbolContext next_line_sc;
     Address range_end(complete_line_range.GetBaseAddress());
     range_end.Slide(complete_line_range.GetByteSize());
-    range_end.CalculateSymbolContext(&next_line_sc,
-                                     lldb::eSymbolContextLineEntry);
+    range_end.CalculateSymbolContext(&next_line_sc, symbol_context_scope);
 
-    if (next_line_sc.line_entry.IsValid() &&
-        next_line_sc.line_entry.range.GetByteSize() > 0 &&
-        original_file == next_line_sc.line_entry.original_file) {
+    if (!next_line_sc.line_entry.IsValid() ||
+        next_line_sc.line_entry.range.GetByteSize() == 0)
+      break;
+
+    if (original_file == next_line_sc.line_entry.original_file &&
+        (next_line_sc.line_entry.line == 0 ||
+         line == next_line_sc.line_entry.line)) {
       // Include any line 0 entries - they indicate that this is compiler-
       // generated code that does not correspond to user source code.
-      if (next_line_sc.line_entry.line == 0) {
-        complete_line_range.SetByteSize(
-            complete_line_range.GetByteSize() +
-            next_line_sc.line_entry.range.GetByteSize());
-        continue;
-      }
-
-      if (line == next_line_sc.line_entry.line) {
-        // next_line_sc is the same file & line as this LineEntry, so extend
-        // our AddressRange by its size and continue to see if there are more
-        // LineEntries that we can combine.
-        complete_line_range.SetByteSize(
-            complete_line_range.GetByteSize() +
-            next_line_sc.line_entry.range.GetByteSize());
-        continue;
-      }
+      // next_line_sc is the same file & line as this LineEntry, so extend
+      // our AddressRange by its size and continue to see if there are more
+      // LineEntries that we can combine. However, if there was nothing to
+      // extend we're done.
+      if (!complete_line_range.Extend(next_line_sc.line_entry.range))
+        break;
+      continue;
+    }
+
+    if (include_inlined_functions && next_line_sc.block &&
+        next_line_sc.block->GetContainingInlinedBlock() != nullptr) {
+      // The next_line_sc might be in a different file if it's an inlined
+      // function. If this is the case then we still want to expand our line
+      // range to include them if the inlined function is at the same call site
+      // as this line entry. The current block could represent a nested inline
+      // function call so we need to need to check up the block tree to see if
+      // we find one.
+      auto inlined_parent_block =
+          next_line_sc.block->GetContainingInlinedBlockWithCallSite(
+              start_call_site);
+      if (!inlined_parent_block)
+        // We didn't find any parent inlined block with a call site at this line
+        // entry so this inlined function is probably at another line.
+        break;
+      // Extend our AddressRange by the size of the inlined block, but if there
+      // was nothing to add then we're done.
+      if (!complete_line_range.Extend(next_line_sc.line_entry.range))
+        break;
+      continue;
     }
+
     break;
   }
   return complete_line_range;
index d100b8b..7817641 100644 (file)
@@ -1395,10 +1395,12 @@ ThreadPlanSP Thread::QueueThreadPlanForStepOverRange(
     bool abort_other_plans, const LineEntry &line_entry,
     const SymbolContext &addr_context, lldb::RunMode stop_other_threads,
     Status &status, LazyBool step_out_avoids_code_withoug_debug_info) {
+  const bool include_inlined_functions = true;
+  auto address_range =
+      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
   return QueueThreadPlanForStepOverRange(
-      abort_other_plans, line_entry.GetSameLineContiguousAddressRange(),
-      addr_context, stop_other_threads, status,
-      step_out_avoids_code_withoug_debug_info);
+      abort_other_plans, address_range, addr_context, stop_other_threads,
+      status, step_out_avoids_code_withoug_debug_info);
 }
 
 ThreadPlanSP Thread::QueueThreadPlanForStepInRange(
@@ -1428,8 +1430,10 @@ ThreadPlanSP Thread::QueueThreadPlanForStepInRange(
     lldb::RunMode stop_other_threads, Status &status,
     LazyBool step_in_avoids_code_without_debug_info,
     LazyBool step_out_avoids_code_without_debug_info) {
+  const bool include_inlined_functions = false;
   return QueueThreadPlanForStepInRange(
-      abort_other_plans, line_entry.GetSameLineContiguousAddressRange(),
+      abort_other_plans,
+      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions),
       addr_context, step_in_target, stop_other_threads, status,
       step_in_avoids_code_without_debug_info,
       step_out_avoids_code_without_debug_info);
index 3461be5..bf55c37 100644 (file)
@@ -110,8 +110,9 @@ ThreadPlanStepOut::ThreadPlanStepOut(
       return_address_decr_pc.CalculateSymbolContext(
           &return_address_sc, lldb::eSymbolContextLineEntry);
       if (return_address_sc.line_entry.IsValid()) {
-        range =
-            return_address_sc.line_entry.GetSameLineContiguousAddressRange();
+        const bool include_inlined_functions = false;
+        range = return_address_sc.line_entry.GetSameLineContiguousAddressRange(
+            include_inlined_functions);
         if (range.GetByteSize() > 0) {
           return_address =
               m_thread.GetProcess()->AdvanceAddressToNextBranchInstruction(
index 7b0a588..e5b3eee 100644 (file)
@@ -126,8 +126,10 @@ bool ThreadPlanStepRange::InRange() {
           new_context.line_entry.original_file) {
         if (m_addr_context.line_entry.line == new_context.line_entry.line) {
           m_addr_context = new_context;
-          AddRange(
-              m_addr_context.line_entry.GetSameLineContiguousAddressRange());
+          const bool include_inlined_functions =
+              GetKind() == eKindStepOverRange;
+          AddRange(m_addr_context.line_entry.GetSameLineContiguousAddressRange(
+              include_inlined_functions));
           ret_value = true;
           if (log) {
             StreamString s;
@@ -142,8 +144,10 @@ bool ThreadPlanStepRange::InRange() {
         } else if (new_context.line_entry.line == 0) {
           new_context.line_entry.line = m_addr_context.line_entry.line;
           m_addr_context = new_context;
-          AddRange(
-              m_addr_context.line_entry.GetSameLineContiguousAddressRange());
+          const bool include_inlined_functions =
+              GetKind() == eKindStepOverRange;
+          AddRange(m_addr_context.line_entry.GetSameLineContiguousAddressRange(
+              include_inlined_functions));
           ret_value = true;
           if (log) {
             StreamString s;
index 3efb26b..aecc778 100644 (file)
@@ -364,8 +364,10 @@ Error opts::symbols::findFunctions(lldb_private::Module &Module) {
       cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
       if (!le.IsValid())
         continue;
-
-      auto addr = le.GetSameLineContiguousAddressRange().GetBaseAddress();
+      const bool include_inlined_functions = false;
+      auto addr =
+          le.GetSameLineContiguousAddressRange(include_inlined_functions)
+              .GetBaseAddress();
       if (!addr.IsValid())
         continue;
 
@@ -414,8 +416,9 @@ Error opts::symbols::findBlocks(lldb_private::Module &Module) {
     cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
     if (!le.IsValid())
       continue;
-
-    auto addr = le.GetSameLineContiguousAddressRange().GetBaseAddress();
+    const bool include_inlined_functions = false;
+    auto addr = le.GetSameLineContiguousAddressRange(include_inlined_functions)
+                    .GetBaseAddress();
     if (!addr.IsValid())
       continue;
 
index dcac714..1a67f34 100644 (file)
@@ -10,13 +10,11 @@ add_lldb_unittest(LLDBCoreTests
     lldbPluginObjectFileELF
     lldbPluginSymbolVendorELF
     lldbUtilityHelpers
+    LLVMTestingSupport
   LINK_COMPONENTS
     Support
   )
 
-add_dependencies(LLDBCoreTests yaml2obj)
-add_definitions(-DYAML2OBJ="$<TARGET_FILE:yaml2obj>")
-
 set(test_inputs
   mangled-function-names.yaml
   )
index a9bef41..85d2723 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
+#include "llvm/Testing/Support/Error.h"
 
 #include "gtest/gtest.h"
 
@@ -49,38 +50,18 @@ TEST(MangledTest, EmptyForInvalidName) {
   EXPECT_STREQ("", TheDemangled.GetCString());
 }
 
-#define ASSERT_NO_ERROR(x)                                                     \
-  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
-    llvm::SmallString<128> MessageStorage;                                     \
-    llvm::raw_svector_ostream Message(MessageStorage);                         \
-    Message << #x ": did not return errc::success.\n"                          \
-            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
-            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
-    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
-  } else {                                                                     \
-  }
-
 TEST(MangledTest, NameIndexes_FindFunctionSymbols) {
   FileSystem::Initialize();
   HostInfo::Initialize();
   ObjectFileELF::Initialize();
   SymbolVendorELF::Initialize();
 
-  std::string Yaml = GetInputFilePath("mangled-function-names.yaml");
   llvm::SmallString<128> Obj;
   ASSERT_NO_ERROR(llvm::sys::fs::createTemporaryFile(
       "mangled-function-names-%%%%%%", "obj", Obj));
-
   llvm::FileRemover Deleter(Obj);
-  llvm::StringRef Args[] = {YAML2OBJ, Yaml};
-  llvm::StringRef ObjRef = Obj;
-  const llvm::Optional<llvm::StringRef> redirects[] = {llvm::None, ObjRef,
-                                                       llvm::None};
-  ASSERT_EQ(0,
-            llvm::sys::ExecuteAndWait(YAML2OBJ, Args, llvm::None, redirects));
-  uint64_t Size;
-  ASSERT_NO_ERROR(llvm::sys::fs::file_size(Obj, Size));
-  ASSERT_GT(Size, 0u);
+  ASSERT_THAT_ERROR(ReadYAMLObjectFile("mangled-function-names.yaml", Obj),
+                    llvm::Succeeded());
 
   ModuleSpec Spec{FileSpec(Obj)};
   Spec.GetSymbolFileSpec().SetFile(Obj, FileSpec::Style::native);
index 8159606..6ad0442 100644 (file)
@@ -15,6 +15,7 @@
 #include "gtest/gtest.h"
 
 #include "TestingSupport/MockTildeExpressionResolver.h"
+#include "TestingSupport/TestUtilities.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -25,17 +26,6 @@ namespace path = llvm::sys::path;
 using namespace llvm;
 using namespace lldb_private;
 
-#define ASSERT_NO_ERROR(x)                                                     \
-  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
-    SmallString<128> MessageStorage;                                           \
-    raw_svector_ostream Message(MessageStorage);                               \
-    Message << #x ": did not return errc::success.\n"                          \
-            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
-            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
-    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
-  } else {                                                                     \
-  }
-
 namespace {
 
 class CompletionTest : public testing::Test {
index d16dc2d..ccce062 100644 (file)
@@ -6,11 +6,9 @@ add_lldb_unittest(ObjectFileELFTests
     lldbPluginSymbolVendorELF
     lldbCore
     lldbUtilityHelpers
+    LLVMTestingSupport
   )
 
-add_dependencies(ObjectFileELFTests yaml2obj)
-add_definitions(-DYAML2OBJ="$<TARGET_FILE:yaml2obj>")
-
 set(test_inputs
   early-section-headers.so
   debug-info-relocations.pcm.yaml
index eab326a..a74986b 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 
 using namespace lldb_private;
@@ -46,33 +47,14 @@ public:
 protected:
 };
 
-#define ASSERT_NO_ERROR(x)                                                     \
-  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
-    llvm::SmallString<128> MessageStorage;                                     \
-    llvm::raw_svector_ostream Message(MessageStorage);                         \
-    Message << #x ": did not return errc::success.\n"                          \
-            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
-            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
-    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
-  } else {                                                                     \
-  }
-
 TEST_F(ObjectFileELFTest, SectionsResolveConsistently) {
-  std::string yaml = GetInputFilePath("sections-resolve-consistently.yaml");
   llvm::SmallString<128> obj;
   ASSERT_NO_ERROR(llvm::sys::fs::createTemporaryFile(
       "sections-resolve-consistently-%%%%%%", "obj", obj));
-
   llvm::FileRemover remover(obj);
-  llvm::StringRef args[] = {YAML2OBJ, yaml};
-  llvm::StringRef obj_ref = obj;
-  const llvm::Optional<llvm::StringRef> redirects[] = {llvm::None, obj_ref,
-                                                       llvm::None};
-  ASSERT_EQ(0,
-            llvm::sys::ExecuteAndWait(YAML2OBJ, args, llvm::None, redirects));
-  uint64_t size;
-  ASSERT_NO_ERROR(llvm::sys::fs::file_size(obj, size));
-  ASSERT_GT(size, 0u);
+  ASSERT_THAT_ERROR(
+      ReadYAMLObjectFile("sections-resolve-consistently.yaml", obj),
+      llvm::Succeeded());
 
   ModuleSpec spec{FileSpec(obj)};
   spec.GetSymbolFileSpec().SetFile(obj, FileSpec::Style::native);
@@ -155,21 +137,12 @@ static void CHECK_ABS64(uint8_t *bytes, uint64_t offset, uint64_t addend) {
 }
 
 TEST_F(ObjectFileELFTest, TestAARCH64Relocations) {
-  std::string yaml = GetInputFilePath("debug-info-relocations.pcm.yaml");
   llvm::SmallString<128> obj;
   ASSERT_NO_ERROR(llvm::sys::fs::createTemporaryFile(
       "debug-info-relocations-%%%%%%", "obj", obj));
-
   llvm::FileRemover remover(obj);
-  llvm::StringRef args[] = {YAML2OBJ, yaml};
-  llvm::StringRef obj_ref = obj;
-  const llvm::Optional<llvm::StringRef> redirects[] = {llvm::None, obj_ref,
-                                                       llvm::None};
-  ASSERT_EQ(0,
-            llvm::sys::ExecuteAndWait(YAML2OBJ, args, llvm::None, redirects));
-  uint64_t size;
-  ASSERT_NO_ERROR(llvm::sys::fs::file_size(obj, size));
-  ASSERT_GT(size, 0u);
+  ASSERT_THAT_ERROR(ReadYAMLObjectFile("debug-info-relocations.pcm.yaml", obj),
+                    llvm::Succeeded());
 
   ModuleSpec spec{FileSpec(obj)};
   spec.GetSymbolFileSpec().SetFile(obj, FileSpec::Style::native);
index a461ae4..8b268e6 100644 (file)
@@ -4,17 +4,21 @@ add_lldb_unittest(SymbolTests
   TestClangASTContext.cpp
   TestDWARFCallFrameInfo.cpp
   TestType.cpp
+  TestLineEntry.cpp
 
   LINK_LIBS
     lldbHost
     lldbSymbol
     lldbUtilityHelpers
     lldbPluginObjectFileELF
+    lldbPluginObjectFileMachO
+    lldbPluginSymbolVendorMacOSX
+    lldbPluginSymbolFileDWARF
+    LLVMTestingSupport
   )
 
-add_dependencies(SymbolTests yaml2obj)
-add_definitions(-DYAML2OBJ="$<TARGET_FILE:yaml2obj>")
 set(test_inputs
   basic-call-frame-info.yaml
+  inlined-functions.yaml
   )
 add_unittest_inputs(SymbolTests "${test_inputs}")
index f968ef2..c0bfa55 100644 (file)
@@ -20,6 +20,7 @@
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Symbol/DWARFCallFrameInfo.h"
 #include "lldb/Utility/StreamString.h"
+#include "llvm/Testing/Support/Error.h"
 
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
@@ -47,17 +48,6 @@ protected:
   void TestBasic(DWARFCallFrameInfo::Type type, llvm::StringRef symbol);
 };
 
-#define ASSERT_NO_ERROR(x)                                                     \
-  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
-    llvm::SmallString<128> MessageStorage;                                     \
-    llvm::raw_svector_ostream Message(MessageStorage);                         \
-    Message << #x ": did not return errc::success.\n"                          \
-            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
-            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
-    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
-  } else {                                                                     \
-  }
-
 namespace lldb_private {
 static std::ostream &operator<<(std::ostream &OS, const UnwindPlan::Row &row) {
   StreamString SS;
@@ -94,23 +84,12 @@ static UnwindPlan::Row GetExpectedRow2() {
 
 void DWARFCallFrameInfoTest::TestBasic(DWARFCallFrameInfo::Type type,
                                        llvm::StringRef symbol) {
-  std::string yaml = GetInputFilePath("basic-call-frame-info.yaml");
   llvm::SmallString<128> obj;
-
   ASSERT_NO_ERROR(llvm::sys::fs::createTemporaryFile(
       "basic-call-frame-info-%%%%%%", "obj", obj));
   llvm::FileRemover obj_remover(obj);
-
-  llvm::StringRef args[] = {YAML2OBJ, yaml};
-  llvm::StringRef obj_ref = obj;
-  const llvm::Optional<llvm::StringRef> redirects[] = {llvm::None, obj_ref,
-                                                       llvm::None};
-  ASSERT_EQ(0,
-            llvm::sys::ExecuteAndWait(YAML2OBJ, args, llvm::None, redirects));
-
-  uint64_t size;
-  ASSERT_NO_ERROR(llvm::sys::fs::file_size(obj, size));
-  ASSERT_GT(size, 0u);
+  ASSERT_THAT_ERROR(ReadYAMLObjectFile("basic-call-frame-info.yaml", obj),
+                    llvm::Succeeded());
 
   auto module_sp = std::make_shared<Module>(ModuleSpec(FileSpec(obj)));
   SectionList *list = module_sp->GetSectionList();
index 36c774c..f59c0c8 100644 (file)
@@ -9,3 +9,6 @@ add_lldb_library(lldbUtilityHelpers
   LINK_COMPONENTS
     Support
   )
+
+add_dependencies(lldbUtilityHelpers yaml2obj)
+add_definitions(-DYAML2OBJ="$<TARGET_FILE:yaml2obj>")
\ No newline at end of file
index 9cf1b18..38f470a 100644 (file)
@@ -10,6 +10,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
 
 extern const char *TestMainArgv0;
 
@@ -19,3 +20,24 @@ std::string lldb_private::GetInputFilePath(const llvm::Twine &name) {
   llvm::sys::path::append(result, "Inputs", name);
   return result.str();
 }
+
+llvm::Error
+lldb_private::ReadYAMLObjectFile(const llvm::Twine &yaml_name,
+                                 llvm::SmallString<128> &object_file) {
+  std::string yaml = GetInputFilePath(yaml_name);
+  llvm::StringRef args[] = {YAML2OBJ, yaml};
+  llvm::StringRef obj_ref = object_file;
+  const llvm::Optional<llvm::StringRef> redirects[] = {llvm::None, obj_ref,
+                                                       llvm::None};
+  if (llvm::sys::ExecuteAndWait(YAML2OBJ, args, llvm::None, redirects) != 0)
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Error running yaml2obj %s.", yaml.c_str());
+  uint64_t size;
+  if (auto ec = llvm::sys::fs::file_size(object_file, size))
+    return llvm::errorCodeToError(ec);
+  if (size == 0)
+    return llvm::createStringError(
+        llvm::inconvertibleErrorCode(),
+        "Empty object file created from yaml2obj %s.", yaml.c_str());
+  return llvm::Error::success();
+}
\ No newline at end of file
index eaaa453..cb9f1df 100644 (file)
@@ -9,11 +9,26 @@
 #ifndef LLDB_UNITTESTS_UTILITY_HELPERS_TESTUTILITIES_H
 #define LLDB_UNITTESTS_UTILITY_HELPERS_TESTUTILITIES_H
 
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/Support/Error.h"
 #include <string>
 
+#define ASSERT_NO_ERROR(x)                                                     \
+  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
+    llvm::SmallString<128> MessageStorage;                                     \
+    llvm::raw_svector_ostream Message(MessageStorage);                         \
+    Message << #x ": did not return errc::success.\n"                          \
+            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
+            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
+    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
+  } else {                                                                     \
+  }
+
 namespace lldb_private {
 std::string GetInputFilePath(const llvm::Twine &name);
+llvm::Error ReadYAMLObjectFile(const llvm::Twine &yaml_name,
+                               llvm::SmallString<128> &obj);
 }
 
 #endif