[Lldb-commits] [lldb] r281690 - First tests for serializing breakpoints.

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 15 18:41:27 PDT 2016


Author: jingham
Date: Thu Sep 15 20:41:27 2016
New Revision: 281690

URL: http://llvm.org/viewvc/llvm-project?rev=281690&view=rev
Log:
First tests for serializing breakpoints.

Plus a few bug fixes I found along the way.

Added:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c
Modified:
    lldb/trunk/include/lldb/API/SBBreakpoint.h
    lldb/trunk/scripts/interface/SBBreakpoint.i
    lldb/trunk/source/API/SBBreakpoint.cpp
    lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp
    lldb/trunk/source/Core/SearchFilter.cpp

Modified: lldb/trunk/include/lldb/API/SBBreakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBreakpoint.h?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBBreakpoint.h (original)
+++ lldb/trunk/include/lldb/API/SBBreakpoint.h Thu Sep 15 20:41:27 2016
@@ -104,6 +104,8 @@ public:
 
   bool GetDescription(lldb::SBStream &description);
 
+  bool GetDescription(lldb::SBStream &description, bool include_locations);
+
   static bool EventIsBreakpointEvent(const lldb::SBEvent &event);
 
   static lldb::BreakpointEventType
@@ -152,6 +154,8 @@ public:
 
   SBBreakpoint GetBreakpointAtIndex(size_t idx);
 
+  SBBreakpoint  FindBreakpointByID(lldb::break_id_t);
+
   void Append(const SBBreakpoint &sb_file);
 
   bool AppendIfUnique(const SBBreakpoint &sb_file);

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile?rev=281690&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile Thu Sep 15 20:41:27 2016
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py?rev=281690&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py Thu Sep 15 20:41:27 2016
@@ -0,0 +1,147 @@
+"""
+Test breakpoint ignore count features.
+"""
+
+from __future__ import print_function
+
+
+import os
+import time
+import re
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class BreakpointSerialization(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @add_test_categories(['pyapi'])
+    def test_resolvers(self):
+        """Use Python APIs to test that we serialize resolvers."""
+        self.build()
+        self.setup_targets_and_cleanup()
+        self.do_check_resolvers()
+
+    def not_test_filters(self):
+        """Use Python APIs to test that we serialize search filters correctly."""
+        self.build()
+        self.setup_targets_and_cleanup()
+        self.check_filters()
+
+    def not_test_options(self):
+        """Use Python APIs to test that we serialize breakpoint options correctly."""
+        self.build()
+        self.setup_targets_and_cleanup()
+        self.check_filters()
+
+    def not_test_complex(self):
+        """Use Python APIs to test that we serialize complex breakpoints correctly."""
+        self.build()
+        self.setup_targets_and_cleanup()
+        self.check_filters()
+
+    def setup_targets_and_cleanup(self):
+        def cleanup ():
+            #self.RemoveTempFile(self.bkpts_file_path)
+
+            if self.orig_target.IsValid():
+                self.dbg.DeleteTarget(self.orig_target)
+                self.dbg.DeleteTarget(self.copy_target)
+
+        self.addTearDownHook(cleanup)
+        #self.RemoveTempFile(self.bkpts_file_path)
+
+        exe = os.path.join(os.getcwd(), "a.out")
+
+        # Create a targets we are making breakpoint in and copying to:
+        self.orig_target = self.dbg.CreateTarget(exe)
+        self.assertTrue(self.orig_target, VALID_TARGET)
+        
+        self.copy_target = self.dbg.CreateTarget(exe)
+        self.assertTrue(self.copy_target, VALID_TARGET)
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+
+        self.bkpts_file_path = os.path.join(os.getcwd(), "breakpoints.json")
+        self.bkpts_file_spec = lldb.SBFileSpec(self.bkpts_file_path)
+
+    def do_check_resolvers(self):
+        """Use Python APIs to check serialization of breakpoint resolvers"""
+
+        empty_module_list = lldb.SBFileSpecList()
+        empty_cu_list = lldb.SBFileSpecList()
+        blubby_file_spec = lldb.SBFileSpec(os.path.join(os.getcwd(), "blubby.c"))
+
+        # It isn't actually important for these purposes that these breakpoint
+        # actually have locations.
+        source_bps = lldb.SBBreakpointList(self.orig_target)
+        source_bps.Append(self.orig_target.BreakpointCreateByLocation("blubby.c", 666))
+        source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list))
+        source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list))
+        source_bps.Append(self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec))
+
+        error = lldb.SBError()
+        error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec)
+        self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
+
+        copy_bps = lldb.SBBreakpointList(self.copy_target)
+        error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, copy_bps)
+        self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
+
+        num_source_bps = source_bps.GetSize()
+        num_copy_bps = copy_bps.GetSize()
+        self.assertTrue(num_source_bps == num_copy_bps, "Didn't get same number of input and output breakpoints - orig: %d copy: %d"%(num_source_bps, num_copy_bps))
+        
+        for i in range(0, num_source_bps):
+            source_bp = source_bps.GetBreakpointAtIndex(i)
+            source_desc = lldb.SBStream()
+            source_bp.GetDescription(source_desc, False)
+            source_text = source_desc.GetData()
+
+            # I am assuming here that the breakpoints will get written out in breakpoint ID order, and
+            # read back in ditto.  That is true right now, and I can't see any reason to do it differently
+            # but if we do we can go to writing the breakpoints one by one, or sniffing the descriptions to
+            # see which one is which.
+            copy_id = source_bp.GetID()
+            copy_bp = copy_bps.FindBreakpointByID(copy_id)
+            self.assertTrue(copy_bp.IsValid(), "Could not find copy breakpoint %d."%(copy_id))
+
+            copy_desc = lldb.SBStream()
+            copy_bp.GetDescription(copy_desc, False)
+            copy_text = copy_desc.GetData()
+
+            # These two should be identical.
+            print ("Source test for %d is %s."%(i, source_text))
+            self.assertTrue (source_text == copy_text, "Source and dest breakpoints are not identical: \nsource: %s\ndest: %s"%(source_text, copy_text))
+
+    def check_filters(self):
+        """Use Python APIs to check serialization of breakpoint filters."""
+        exe = os.path.join(os.getcwd(), "a.out")
+
+        # Create a target by the debugger.
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+    def check_options(self):
+        """Use Python APIs to check serialization of breakpoint options."""
+        exe = os.path.join(os.getcwd(), "a.out")
+
+        # Create a target by the debugger.
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+    def check_resolvers(self):
+        """Use Python APIs to check serialization of breakpoint resolvers."""
+        exe = os.path.join(os.getcwd(), "a.out")
+
+        # Create a target by the debugger.
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+
+        

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c?rev=281690&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c Thu Sep 15 20:41:27 2016
@@ -0,0 +1,54 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+// This simple program is to demonstrate the capability of the lldb command
+// "breakpoint modify -i <count> breakpt-id" to set the number of times a
+// breakpoint is skipped before stopping.  Ignore count can also be set upon
+// breakpoint creation by 'breakpoint set ... -i <count>'.
+
+int a(int);
+int b(int);
+int c(int);
+
+int a(int val)
+{
+    if (val <= 1)
+        return b(val);
+    else if (val >= 3)
+        return c(val); // a(3) -> c(3) Find the call site of c(3).
+
+    return val;
+}
+
+int b(int val)
+{
+    return c(val);
+}
+
+int c(int val)
+{
+    return val + 3; // Find the line number of function "c" here.
+}
+
+int main (int argc, char const *argv[])
+{
+    int A1 = a(1);  // a(1) -> b(1) -> c(1)
+    printf("a(1) returns %d\n", A1);
+    
+    int B2 = b(2);  // b(2) -> c(2) Find the call site of b(2).
+    printf("b(2) returns %d\n", B2);
+    
+    int A3 = a(3);  // a(3) -> c(3) Find the call site of a(3).
+    printf("a(3) returns %d\n", A3);
+    
+    int C1 = c(5); // Find the call site of c in main.
+    printf ("c(5) returns %d\n", C1);
+    return 0;
+}

Modified: lldb/trunk/scripts/interface/SBBreakpoint.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBBreakpoint.i?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBBreakpoint.i (original)
+++ lldb/trunk/scripts/interface/SBBreakpoint.i Thu Sep 15 20:41:27 2016
@@ -221,6 +221,9 @@ public:
     bool
     GetDescription (lldb::SBStream &description);
 
+    bool 
+    GetDescription(lldb::SBStream &description, bool include_locations);
+
     bool
     operator == (const lldb::SBBreakpoint& rhs);
            
@@ -276,6 +279,9 @@ public:
   
   SBBreakpoint
   GetBreakpointAtIndex(size_t idx);
+  
+  SBBreakpoint
+  FindBreakpointByID(lldb::break_id_t);
 
   void Append(const SBBreakpoint &sb_bkpt);
 

Modified: lldb/trunk/source/API/SBBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpoint.cpp?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/source/API/SBBreakpoint.cpp (original)
+++ lldb/trunk/source/API/SBBreakpoint.cpp Thu Sep 15 20:41:27 2016
@@ -449,14 +449,20 @@ size_t SBBreakpoint::GetNumLocations() c
 }
 
 bool SBBreakpoint::GetDescription(SBStream &s) {
+  return GetDescription(s, true);
+}
+
+bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
   if (m_opaque_sp) {
     std::lock_guard<std::recursive_mutex> guard(
         m_opaque_sp->GetTarget().GetAPIMutex());
     s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
     m_opaque_sp->GetResolverDescription(s.get());
     m_opaque_sp->GetFilterDescription(s.get());
-    const size_t num_locations = m_opaque_sp->GetNumLocations();
-    s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
+    if (include_locations) {
+      const size_t num_locations = m_opaque_sp->GetNumLocations();
+      s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
+    }
     return true;
   }
   s.Printf("No value");
@@ -702,6 +708,18 @@ public:
     return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
   }
 
+  BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
+    TargetSP target_sp = m_target_wp.lock();
+    if (!target_sp)
+      return BreakpointSP();
+
+    for (lldb::break_id_t &break_id : m_break_ids) {
+      if (break_id == desired_id)
+        return target_sp->GetBreakpointList().FindBreakpointByID(break_id);
+    }
+    return BreakpointSP();
+  }
+
   bool Append(Breakpoint &bkpt) {
     TargetSP target_sp = m_target_wp.lock();
     if (!target_sp)
@@ -772,6 +790,13 @@ SBBreakpoint SBBreakpointList::GetBreakp
   return SBBreakpoint(bkpt_sp);
 }
 
+SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
+  if (!m_opaque_sp)
+    return SBBreakpoint();
+  BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
+  return SBBreakpoint(bkpt_sp);
+}
+
 void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
   if (!sb_bkpt.IsValid())
     return;

Modified: lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp Thu Sep 15 20:41:27 2016
@@ -30,7 +30,7 @@ using namespace lldb_private;
 BreakpointResolverFileRegex::BreakpointResolverFileRegex(
     Breakpoint *bkpt, RegularExpression &regex,
     const std::unordered_set<std::string> &func_names, bool exact_match)
-    : BreakpointResolver(bkpt, BreakpointResolver::FileLineResolver),
+    : BreakpointResolver(bkpt, BreakpointResolver::FileRegexResolver),
       m_regex(regex), m_exact_match(exact_match), m_function_names(func_names) {
 }
 

Modified: lldb/trunk/source/Core/SearchFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/SearchFilter.cpp?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/source/Core/SearchFilter.cpp (original)
+++ lldb/trunk/source/Core/SearchFilter.cpp Thu Sep 15 20:41:27 2016
@@ -37,7 +37,7 @@ const char *SearchFilter::FilterTyToName
 }
 
 SearchFilter::FilterTy SearchFilter::NameToFilterTy(const char *name) {
-  for (size_t i = 0; i < LastKnownFilterType; i++) {
+  for (size_t i = 0; i <= LastKnownFilterType; i++) {
     if (strcmp(name, g_ty_to_name[i]) == 0)
       return (FilterTy)i;
   }
@@ -163,8 +163,13 @@ SearchFilter::WrapOptionsDict(Structured
 void SearchFilter::SerializeFileSpecList(
     StructuredData::DictionarySP &options_dict_sp, OptionNames name,
     FileSpecList &file_list) {
-  StructuredData::ArraySP module_array_sp(new StructuredData::Array());
   size_t num_modules = file_list.GetSize();
+
+  // Don't serialize empty lists.
+  if (num_modules == 0)
+    return;
+
+  StructuredData::ArraySP module_array_sp(new StructuredData::Array());
   for (size_t i = 0; i < num_modules; i++) {
     module_array_sp->AddItem(StructuredData::StringSP(
         new StructuredData::String(file_list.GetFileSpecAtIndex(i).GetPath())));
@@ -630,22 +635,19 @@ SearchFilterSP SearchFilterByModuleList:
   StructuredData::Array *modules_array;
   bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
                                                  modules_array);
-  if (!success) {
-    error.SetErrorString("SFBM::CFSD: Could not find the module list key.");
-    return nullptr;
-  }
-
-  size_t num_modules = modules_array->GetSize();
   FileSpecList modules;
-  for (size_t i = 0; i < num_modules; i++) {
-    std::string module;
-    success = modules_array->GetItemAtIndexAsString(i, module);
-    if (!success) {
-      error.SetErrorStringWithFormat(
-          "SFBM::CFSD: filter module item %zu not a string.", i);
-      return nullptr;
+  if (success) {
+    size_t num_modules = modules_array->GetSize();
+    for (size_t i = 0; i < num_modules; i++) {
+      std::string module;
+      success = modules_array->GetItemAtIndexAsString(i, module);
+      if (!success) {
+        error.SetErrorStringWithFormat(
+            "SFBM::CFSD: filter module item %zu not a string.", i);
+        return nullptr;
+      }
+      modules.Append(FileSpec(module.c_str(), false));
     }
-    modules.Append(FileSpec(module.c_str(), false));
   }
 
   return SearchFilterSP(
@@ -694,29 +696,26 @@ SearchFilterByModuleListAndCU::~SearchFi
 
 lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData(
     Target &target, const StructuredData::Dictionary &data_dict, Error &error) {
-  StructuredData::Array *modules_array;
+  StructuredData::Array *modules_array = nullptr;
   SearchFilterSP result_sp;
   bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
                                                  modules_array);
-  if (!success) {
-    error.SetErrorString("SFBM::CFSD: Could not find the module list key.");
-    return result_sp;
-  }
-
-  size_t num_modules = modules_array->GetSize();
   FileSpecList modules;
-  for (size_t i = 0; i < num_modules; i++) {
-    std::string module;
-    success = modules_array->GetItemAtIndexAsString(i, module);
-    if (!success) {
-      error.SetErrorStringWithFormat(
-          "SFBM::CFSD: filter module item %zu not a string.", i);
-      return result_sp;
+  if (success) {
+    size_t num_modules = modules_array->GetSize();
+    for (size_t i = 0; i < num_modules; i++) {
+      std::string module;
+      success = modules_array->GetItemAtIndexAsString(i, module);
+      if (!success) {
+        error.SetErrorStringWithFormat(
+            "SFBM::CFSD: filter module item %zu not a string.", i);
+        return result_sp;
+      }
+      modules.Append(FileSpec(module.c_str(), false));
     }
-    modules.Append(FileSpec(module.c_str(), false));
   }
 
-  StructuredData::Array *cus_array;
+  StructuredData::Array *cus_array = nullptr;
   success =
       data_dict.GetValueForKeyAsArray(GetKey(OptionNames::CUList), cus_array);
   if (!success) {
@@ -728,7 +727,7 @@ lldb::SearchFilterSP SearchFilterByModul
   FileSpecList cus;
   for (size_t i = 0; i < num_cus; i++) {
     std::string cu;
-    success = modules_array->GetItemAtIndexAsString(i, cu);
+    success = cus_array->GetItemAtIndexAsString(i, cu);
     if (!success) {
       error.SetErrorStringWithFormat(
           "SFBM::CFSD: filter cu item %zu not a string.", i);




More information about the lldb-commits mailing list